IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

Petit problème de fork


Sujet :

Linux

  1. #1
    Futur Membre du Club
    Inscrit en
    Novembre 2002
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 6
    Points : 7
    Points
    7
    Par défaut Petit problème de fork
    Bonjour,

    J'ai un petit problème dans le code ci-dessous (le but de ce programme est que le proces père attende la fin de chacun des process fils qu'il créer).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    int main() {
    	int pidFils1; /* Valeur de retour de la fonction fork */
    	int pidFils2; /* Valeur de retour de la fonction fork (2eme utilisation)*/
    	int pidPere; /* PID du processus parent */
     
    	/* SI erreur de creation d'un processus */
    	if((pidFils1 = fork()) == -1) {
    		perror("Erreur de creation du processus 1");
    		exit(0);
    	}
     
    	/* Processus fils 1 */
    	if(pidFils1 == 0) {
    		printf("Processus Fils 1\n");
    		printf("PID  : %d\nPPID : %d\n", getpid(), getppid());
    		sleep(3); /* Pause de 3 secondes */
    		printf("Fin du process Fils 1\n");
    	}
    	else {/* Processus pere */
    		/* SI erreur de creation */
    		if((pidFils2 = fork()) == -1) {
    			perror("Erreur de creation du processus 2");
    			exit(0);
    		}
     
    		/* Processus fils 2 */
    		if(pidFils2 == 0) {
    			printf("Processus Fils 2\n");
    			printf("PID  : %d\nPPID : %d\n", getpid(), getppid());
    			sleep(5); /* Pause de 5 secondes */
    			printf("Fin du process Fils 2\n");
    		}
    		else {
    			printf("Pere en attente du fils 1...\n");
    			waitpid(pidFils1);
     
    			printf("Pere en attente du fils 2...\n");
    			waitpid(pidFils2);
     
    			printf("Processus Pere\n");
    			printf("PID       : %d\nPID-Fils1 : %d\nPID-Fils2 : %d\n", getpid(), pidFils1, pidFils2);
    		}
    	}
     
    	return 0;
    }
    Le problème, c'est qu'il ne les attend pas. Voici le résultat que j'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ./fork
    Processus Fils 1
    PID  : 4184
    PPID : 4183
    Processus Fils 2
    PID  : 4185
    PPID : 4183
    Pere en attente du fils 1...
    Pere en attente du fils 2...
    Processus Pere
    PID       : 4183
    PID-Fils1 : 4184
    PID-Fils2 : 4185
    [nicolas@localhost Desktop]$ Fin du process Fils 1
    Fin du process Fils 2

  2. #2
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Bonsoir!

    Je n'en suis pas sûr, mais ton code en C est peut-être bon. Il faut savoir que quand tu écris la commande printf, les données à afficher ne le sont pas immédiatement. Les données sont d'abord redirigées vers un buffer (un fichier temporaire) et sont affichées toutes en mêmes temps, soit lorsque le buffer est plein, soit lorsque le processus est arrêté. Par contre tu peux forcer l'exécution immédiate de la commande printf en écrivant en dessous de CHAQUE commande la commande

    Cette petite astuce te permettra déjà de savoir si effectivement ton processus père se termine avant son fils ou bien s'il ne s'agit que d'un petit prolème d'affichage...

    Dans tous les cas, je te conseille de t'adresser directement au forum C du site www.Developpez.net, à l'adresse suivante :

    http://www.developpez.net/forums/viewforum.php?f=6

    Tu y trouveras certainement des personnes beaucoup plus compétantes que moi pour répondre à ce genre de question...

    kennystar.

  3. #3
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 289
    Points : 342
    Points
    342
    Par défaut
    Normalement, le tampon de la sortie standard est vidé quand le processus se termine... (enfin, normalement)

    Par contre, c'est l'usage de waitpid() qui est incomplet : la version dont je dispose sur mon poste accepte 3 arguments, cf. la page de manuel appropriée. En ajoutant les bons #include, et en compilant avec les tous les avertissements possibles (-Wall -ansi -pedantic si tu utilises gcc), ce genre d'erreurs se trouve rapidement. Le code suivant marche chez moi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/wait.h>
     
    int main(void) {
       int pidFils1; /* Valeur de retour de la fonction fork */
       int pidFils2; /* Valeur de retour de la fonction fork (2eme utilisation)*/
       int status;
     
       /* SI erreur de creation d'un processus */
       if((pidFils1 = fork()) == -1) {
           perror("Erreur de creation du processus 1");
           exit(EXIT_SUCCESS);
       }
     
       /* Processus fils 1 */
       if(pidFils1 == 0) {
           printf("Processus Fils 1\n");
           printf("PID  : %d\nPPID : %d\n", getpid(), getppid());
           sleep(3); /* Pause de 3 secondes */
           printf("Fin du process Fils 1\n");
       } else {/* Processus pere */
           /* SI erreur de creation */
           if((pidFils2 = fork()) == -1) {
               perror("Erreur de creation du processus 2");
               exit(EXIT_SUCCESS);
           }
     
           /* Processus fils 2 */
           if(pidFils2 == 0) {
               printf("Processus Fils 2\n");
               printf("PID  : %d\nPPID : %d\n", getpid(), getppid());
               sleep(5); /* Pause de 5 secondes */
               printf("Fin du process Fils 2\n");
           } else {
               printf("Pere en attente du fils 1...\n");
               if (waitpid(pidFils1, &status, 0) == -1) {
                   printf(".. erreur de waitpid\n");
               } else {
                   printf("%s\n", WIFEXITED(status) ? "...s'est terminé normalement" : "...erreur !");
               }
     
               printf("Pere en attente du fils 2...\n");
               if (waitpid(pidFils2, &status, 0) == -1) {
                   printf(".. erreur de waitpid\n");
               } else {
                   printf("%s\n", WIFEXITED(status) ? "...s'est terminé normalement" : "...erreur !");
               }
     
               printf("Processus Pere\n");
               printf("PID       : %d\nPID-Fils1 : %d\nPID-Fils2 : %d\n", getpid(), pidFils1, pidFils2);
           }
       }
     
       exit(EXIT_SUCCESS);
    }
    Chez moi, ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    $ gcc -c dev.c -Wall -ansi -pedantic
    $ gcc -o dev dev.o
    $ ./dev
    Pere en attente du fils 1...
    Processus Fils 1
    PID  : 17382
    PPID : 10860
    Processus Fils 2
    PID  : 7361
    PPID : 10860
    Fin du process Fils 1
    ...s'est terminé normalement
    Pere en attente du fils 2...
    Fin du process Fils 2
    ...s'est terminé normalement
    Processus Pere
    PID       : 10860
    PID-Fils1 : 17382
    PID-Fils2 : 7361
    De plus:
    - il est mieux de faire exit() depuis la fonction main, et non return.
    - les codes de sortie à utiliser sont EXIT_SUCCESS et EXIT_FAILURE (leur valeur numérique dépend des systèmes).
    - main() n'a que deux prototypes, l'un avec (void) comme paramètres, l'autre avec (int argc, char *argv[]). De manière générale, une fonction qui n'accepte aucun paramètre doit être déclarée avec le paramètre (void).
    - tout résultat d'un appel à une fonction de bibliothèque doit être vérifié (surtout des trucs du genre fork/wait/waitpid...) (et note que je n'ai pas forcément rajouté tous les tests nécessaires).

  4. #4
    Futur Membre du Club
    Inscrit en
    Novembre 2002
    Messages
    6
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 6
    Points : 7
    Points
    7
    Par défaut Merci
    Merci, le code du dernier message fonctionne correctement !

  5. #5
    Expert confirmé
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 861
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 861
    Points : 4 828
    Points
    4 828
    Par défaut
    Un petit tag résolu, s'il te plait

  6. #6
    Membre averti

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    289
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 289
    Points : 342
    Points
    342
    Par défaut
    Vérifie quand même le fonctionnement de waitpid(), je ne suis pas sûr pour le rôle du troisième argument (les options)...

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    bonjour
    ma question est:
    quand le processus disparait que renvoit getppid()

  8. #8
    Membre actif
    Homme Profil pro
    Analyste/développeur Java EE
    Inscrit en
    Janvier 2005
    Messages
    376
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste/développeur Java EE

    Informations forums :
    Inscription : Janvier 2005
    Messages : 376
    Points : 271
    Points
    271
    Par défaut
    Quand le processus père meurt? Et que les deux fils existent toujours, ils sont hérités par le processus 1.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Aide fork() petit-fils gérés par le père ?
    Par Drexler82 dans le forum Programmation et administration système
    Réponses: 15
    Dernier message: 07/06/2011, 15h04
  2. petite précision concernant l'appel de fork()
    Par jackk dans le forum Administration système
    Réponses: 8
    Dernier message: 27/10/2009, 15h50
  3. Programme à réaliser en C(petit probl)
    Par conceicao dans le forum C
    Réponses: 32
    Dernier message: 24/11/2006, 09h46
  4. [Syntaxe] PETIT probl avec un Jlabel
    Par blackcrow1981 dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 14/09/2006, 19h53
  5. Une petite aide pour les API ?
    Par Yop dans le forum Windows
    Réponses: 2
    Dernier message: 04/04/2002, 21h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo