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

POSIX C Discussion :

Double fork et communication par tubes, terminaison précoce.


Sujet :

POSIX C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2011
    Messages : 22
    Points : 21
    Points
    21
    Par défaut Double fork et communication par tubes, terminaison précoce.
    Bonjour,
    Je rencontre une anomalie à l'éxecution d'un petit programme c sous openindiana.

    Voici le code:
    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
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/time.h>
    #include <sys/wait.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <wait.h>
    #define BUF_SIZE 5
    #define NB 5
    extern int errno;
     
    int main(int argc, char * argv[]){
     
    	int fd[2];
    	int err = pipe(fd);
    	if(err == -1) perror(strerror(errno));
     
    	int fd3[2];
    	err = pipe(fd3);
    	if(err == -1) perror(strerror(errno));
     
    	int fd2[2];
    	err = pipe(fd2);
    	if(err == -1) perror(strerror(errno));
     
    	int second;
     
    	int child = fork();
    	if(child == -1){
    		perror("Erreur de création de processus fils.");
    		perror(strerror(errno));
    	}else if(child == 0){
    		printf("Je suis le premier fils pid: %d ppid: %d\n",getpid(),getppid());
    		close(fd[1]);
    		close(fd2[0]);
    		close(fd3[0]);
    		close(fd3[1]);
    		char nb_buf[BUF_SIZE];
    		err = read(fd[0],nb_buf,BUF_SIZE);
    		if(err == -1){
    			perror("Erreur en lecture au niveau du premier fils.");
    			perror(strerror(errno));
    		}	
    		int nb = atoi(nb_buf);
    		printf("Il en veut %d.\n",nb);
    		nb = 5;
    		printf("nb = %d",nb);
    		int rand_tab[nb];
    		//nb_random(rand_tab,nb,9);
    		rand_tab[0] = 3;
    		rand_tab[1] = 5;
    		rand_tab[2] = 1;
    		rand_tab[3] = 9;
    		rand_tab[4] = 2;
    		char buffer[nb];
    		int i;
    		for(i=0; i<nb; ++i){
    			sprintf(buffer+i,"%s",rand_tab[i]);
    		}
    		int k;
    		for(k=0; k<nb; ++k){
    			printf("tab %d = %d\n",k,rand_tab[k]);
    			printf("tab %s = %d\n",k,buffer[k]);
    		}
    		err = write(fd2[1],&nb,sizeof(int));
    		if(err == -1){
    			perror("Erreur en écriture au niveau du premier fils.");
    			perror(strerror(errno));
    		}
    		err = write(fd2[1],buffer,strlen(buffer));
    		if(err == -1){
    			perror("Erreur en écriture au niveau du premier fils.");
    			perror(strerror(errno));
    		}	
    		exit(EXIT_SUCCESS);
    	}else if(child > 0){			
    		second=fork();
    		if(second > 0){
    			close(fd[0]);
    			close(fd2[0]);
    			close(fd2[1]);
    			close(fd3[1]);
    			printf("Combien de nombres ?\n");
    			char buf[BUF_SIZE];
    			fgets(buf,BUF_SIZE,stdin);
    			printf("Vous en voulez %d.\n",atoi(buf));
    			err = write(fd[1],buf,BUF_SIZE);
    			int status2;
    			wait(&status2);
    			if(WIFEXITED(status2)) printf("terminaison fils 2\n");
    		}else if(second == 0){
    			printf("Je suis le second fils pid: %d ppid: %d\n",getpid(),getppid());
    			close(fd[0]);
    			close(fd[1]);
    			close(fd2[1]);
    			close(fd3[0]);
    			int size;
    			err = read(fd2[0],&size,sizeof(int));
    			if(err == -1){
    				perror("Erreur en lecture au niveau du deuxieme fils.");
    				perror(strerror(errno));
    			}
    			char bufo[size];
    			err = read(fd2[0],bufo,strlen(bufo));
    			if(err == -1){
    				perror("Erreur en lecture au niveau du deuxieme fils.");
    				perror(strerror(errno));
    			}
     
    			printf("size = %d\n",size);
    			int j;
    			for(j=0; j<size; ++j) printf("%s\n",bufo[j]);
    			exit(EXIT_SUCCESS);
    		}else{
    			perror("Erreur de creation du second fils.");
    			perror(strerror(errno));
    		}
    		int status;
    		wait(&status);
    		if(WIFEXITED(status)) printf("terminaison fils 1");
    	}
     
    	return EXIT_SUCCESS;
    }
    A l'éxecution j'obtiens:
    Je suis le premier fils pid: 2184 ppid: 2183
    Je suis le second fils pid: 2185 ppid: 2183
    Combien de nombres ?
    $ 6
    Vous en voulez 6.
    Il en veut 6.

    Au sein du premier fils, l'éxecution semble ne jamais dépasser la ligne 49.
    Au sein du second, on atteint jamais la ligne 113.
    J'ai d'abord pensé à une terminaison précoce du père et donc revu la manière d'utiliser les appels wait, mais sans succès. De plus le test de terminaison d'un des fils, à la ligne 93 n'affiche rien. GDB m'indique que le programme se termine normalement.
    Auriez vous une idée concernant mon erreur ?

    Merci par avance.
    Ben

  2. #2
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Il y a pas mal de problèmes. Pas sûr que ça règle ton problème, mais tu devrais déjà régler ça :

    - perror() affiche déjà strerror(errno)
    - rand_tab[i] est un int, et tu utilises %s dans ton sprintf. Don sprintf() va aller lire les addresses 3, 5, 1, etc, ce qui est évidemment incorrect et pourrait potentiellement faire segfaulter ton process. S'il n'y a pas de segfault à ce niveau là il y a toutes les chances que ça aille jardiner après ton buffer, et que ça segfault plus loin.
    - Quand tu fais un wait() tu ne peux pas savroi quel fils va finir en premier. Ton message "terminaison fils X" est donc potentiellement incorrect.
    - Tu lis strlen(bufo) alors que bufo n'a pas été initialisé. Je pense que tu veux plutôt lire size octets.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2011
    Messages : 22
    Points : 21
    Points
    21
    Par défaut
    Merci matafan, je prend bonne note de tes indications et j'effectue les modifications.
    Malgrès ça j'ai toujours le même problème qu'au départ, je reste donc attentif à toute autre réponse et je continue mes recherches.

    Ben

  4. #4
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Je te suggère de poster ton nouveau code.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2011
    Messages : 22
    Points : 21
    Points
    21
    Par défaut
    Toutes mes excuses j'ai dis une bétise lors de mon dernier post. matafan le fait d'utiliser sprintf avec le format %s semble être à l'origine de mon problème. Lorsque j'utilise spritf(buffer+i,"%d",rand_tab[i]);, le programme s'éxecute normalement. Un grand merci !

    Topic résolu.
    Bonne journée.

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

Discussions similaires

  1. Communication par tubes
    Par stoner dans le forum Débuter
    Réponses: 2
    Dernier message: 26/02/2013, 22h58
  2. Communication par tube
    Par Laurent4033 dans le forum C
    Réponses: 2
    Dernier message: 27/11/2012, 10h25
  3. Réponses: 0
    Dernier message: 30/10/2012, 22h34
  4. Communication inter-processus par tubes nommés
    Par arkham55 dans le forum Shell et commandes POSIX
    Réponses: 3
    Dernier message: 05/05/2012, 20h12
  5. Réponses: 3
    Dernier message: 19/10/2011, 16h52

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