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 :

Tubes et processus fils


Sujet :

Linux

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    26
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 26
    Points : 23
    Points
    23
    Par défaut Tubes et processus fils
    Bonjour, j'essaie de mettre en place un programme C qui permet de réaliser ceci :
    Un processus père P0 lit dans un fichier un texte de plusieurs dizaines de caractères. Il le segmente en paquets de 8 caractères et numérote chaque paquet.
    Au fur et à mesure que les paquets sont constitués, le père transmet le paquet à l'un de ses 3 fils P1, P2, P3 choisi aléatoirement. Chacun de ses fils traite un paquet reçu en le retenant aléatoirement entre 1 et 4 secondes, puis le transmet à P4.

    P4 réordonne les paquets reçus et affiche le message lorsque tous les paquets ont été reçus.

    Voici le code source que j'ai terminé de réaliser mais qui comporte des erreurs, en effet, à la fin les processus fils transmettent 1 paquet au processus P4 par un tube : normalement il doit stocker tous les paquets qu'il reçoit, mais là dans mon code source, il ne garde en mémoire que le dernier paquet envoyé :
    Code c : 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
    128
    129
    130
    131
    132
     
    #include <stdlib.h>
    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
     
    #define TAILLE 20
    int subString(const char *chaine, int debut, int fin, char *result){
        result[fin+1-debut]='\0';
        memcpy(result,(char *)chaine+debut,fin+1-debut);
        return (fin+1-debut);
    }
    int Random (int _iMin, int _iMax) //Permet de génerer un nombre entre _iMin et _iMax
    {
        return (_iMin + (rand () % (_iMax-_iMin+1)));
    }
     
    int main(){
    	int i=0,ret,pidf1,pidf2,pidf3,pidf4;
    	char tab[50];
    	int p_choisi;
    	char chainecouper[10];
    	char reception1[50]="";
    	char reception2[50]="";
    	int p1[2],p2[2],p3[2],p4[2];
     
    	FILE* fichier = NULL;
    	char chaine[50] = "";
     
         fichier = fopen("test.txt", "r");
         if(pipe(p1)||pipe(p2)||pipe(p3)||pipe(p4))
         {
            perror("erreur de creation du tube");
            exit(1);
         }
        if (fichier != NULL)
        {
            fgets(chaine, 20, fichier); 
            printf("Texte ! %s\n", chaine); // On affiche la chaîne
            printf("Taille %d\n", strlen(chaine)-1);
            fclose(fichier);
        }
     
        pidf1=fork();
        pidf2=fork();
        pidf3=fork();
        pidf4=fork();
     
         while(i<strlen(chaine)-1){
         	if((pidf1>0) && (pidf2>0) && (pidf3>0) & (pidf4>0)) {
         		subString(chaine,i,i+7,chainecouper);
         	}
         	//P1 ou P2 ou P3 reçoit le paquet et le mémorise
         	p_choisi=Random(1,3);
         	//printf("Choix %d\n",p_choisi);
    	switch(p_choisi){
            	case 1:
    	    	   if(pidf1==0){//nous sommes dans le fils1 
    			read(p1[0],reception1,TAILLE);
    			write(p4[1],reception1,TAILLE);
    			sleep(Random(1,4));
    			printf("\t le fils 1 a lu %s dans le tube p1 et ecrit cette valeur dans le tube p4\n",reception1);
    			exit(0);
    	    	   }
    	    	   if((pidf1>0) && (pidf2>0) && (pidf3>0) & (pidf4>0)){ //sinon nous sommes dans le père
    			write(p1[1],chainecouper,strlen(chainecouper));
    			printf("le pere ecrit %s dans p1\n", chainecouper);
    			wait(0);
    	    	   }
    	    	   if(pidf4==0){
    			sleep(Random(1,3));
    			printf("le fils 4 reordonne les paquets\n");
    			exit(0);
    	    	   }
    	    	break;
            	case 2:
    	    	   if(pidf2==0){
                	   //le fils 2 lit dans le tube du père
    			read(p2[0],reception1,TAILLE);
    			write(p4[1],reception1,TAILLE);
    			sleep(Random(1,4));
    			printf("\tle fils 2 a lu %s dans le tube p1 et ecrit cette valeur dans le tube p4\n",reception1);
    			exit(0);
                	   }
    	    	   if((pidf1>0) && (pidf2>0) && (pidf3>0) & (pidf4>0)) { //sinon nous sommes dans le père
    			write(p2[1],chainecouper,strlen(chainecouper));
    			printf("le pere ecrit %s dans p2\n",chainecouper);
    			wait(0);
    	          }
    	    	  if(pidf4==0){
    			sleep(Random(1,3));
    			printf("le fils 4 reordonne les paquets\n");
    			exit(0);
    	    	  }
                	break;
    		case 3:
                	   if(pidf3==0){
                 	   //le fils 1 lit dans le tube du père
    			read(p3[0],reception1,TAILLE);
    			write(p4[1],reception1,TAILLE);
    			sleep(Random(1,4));
    			printf("\tle fils 3 a lu %s dans le tube p3 et ecrit cette valeur dans le tube p4\n",reception1);
    			exit(0);
                	  }
    	    	  if((pidf1>0) && (pidf2>0) && (pidf3>0) & (pidf4>0)) { 
    		  //sinon nous sommes dans le père
    			write(p3[1],chainecouper,strlen(chainecouper));
    			printf("le pere ecrit %s dans p3\n",chainecouper);
    			wait(0);
    	    	  }
    	    	  if(pidf4==0){
    	    		sleep(Random(1,3));
                		printf("le fils 4 reordonne les paquets\n");
    	    		exit(0);
    		  }
                	break;
            }//Fin du Switch
     
         	if((pidf1>0) && (pidf2>0) && (pidf3>0) & (pidf4>0)) {
         		//affichage du resultat de la chaine coupée
         		printf("Temp original %s\n",chainecouper);
         		printf("\n");
         		read(p4[0],tab,50);
         		printf("\tContenu du tube 4 %s\n", tab);
         		printf("Indice i %d\n",i);
         		i=i+8;
         	}
     
     
         }//Fin de la boucle while
         printf("FIN\n ");
     }

    Pouvez vous m'aider à résolver ce petit problème de tubes ?
    Merci d'avance.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 12
    Points : 10
    Points
    10
    Par défaut
    Lol ça sent un peu le pompage là... Tu serais pas en L3 MIAGe a Lyon 1 toi un peu? xD

    GRRRIIIIIIIILLLLLLéééééé

  3. #3
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Citation Envoyé par Jopzeut
    Voici le code source que j'ai terminé de réaliser mais qui comporte des erreurs
    En effet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    pipe.c: In function 'main':
    pipe.c:31: warning: implicit declaration of function 'pipe'
    pipe.c:44: warning: implicit declaration of function 'fork'
    pipe.c:49: warning: comparison between signed and unsigned
    pipe.c:59: warning: implicit declaration of function 'read'
    pipe.c:60: warning: implicit declaration of function 'write'
    pipe.c:61: warning: implicit declaration of function 'sleep'
    pipe.c:68: warning: implicit declaration of function 'wait'
    pipe.c:24: warning: unused variable 'reception2'
    pipe.c:19: warning: unused variable 'ret'
    pipe.c:132: warning: control reaches end of non-void function
    en effet, à la fin les processus fils transmettent 1 paquet au processus P4 par un tube : normalement il doit stocker tous les paquets qu'il reçoit, mais là dans mon code source, il ne garde en mémoire que le dernier paquet envoyé
    Ca c'est un problème algorithmique. Qu'est-ce que tu ne comprends pas ? Il suffit de faire une liste chaînée ou un tableau qui contient tous les paquets.

    Ensuite pour le code :

    - Pas d'appel à srand.

    - Si un des pipes ne s'ouvre pas, tu ne refermes pas proprement les autres.
    - Si les pipes s'ouvrent, il faut fermer les côtés qu'on utilise pas. Du coup, le premier fils doit fermer le côté écriture de p1, p2,p3 et le côté lecture de p4. Ci-dessous la bonne facon de créer un fork, du coup, chaque fils aura juste à fermer son propre pipe et celui menant à p4.

    - Si fichier == NULL, chaine sera utilisée non initialisée


    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        pidf1=fork();
        pidf2=fork();
        pidf3=fork();
        pidf4=fork();

    - Aucun test sur le retour des forks, pire, tu va avoir en fait 16 processus parce que tu n'as pas fait les choses correctement. Il faut faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    pid1 = fork();
    if(pid1 != 0) {
       /* Pere */
       pid2 = fork();
    }
    else {
      /* Fils */
      ...
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
         while(i<strlen(chaine)-1){
         	if((pidf1>0) && (pidf2>0) && (pidf3>0) & (pidf4>0)) {
         		subString(chaine,i,i+7,chainecouper);
         	}
    - Tu vas sortir de la longueur de chaîne et donc provoquer un comportement indéterminé car tu ne fais aucun test dans ta fonction subString pour vérifier que le memcpy sera correct.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
         	//P1 ou P2 ou P3 reçoit le paquet et le mémorise
         	p_choisi=Random(1,3);
    Génial, les processus fils doivent attendre d'avoir le bon random pour attendre leur paquet... Avec ma facon de faire les forks, on sait tout de suite où commence et se termine le code des fils.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    			read(p1[0],reception1,TAILLE);
    			write(p4[1],reception1,TAILLE);
    		        ....
    			write(p1[1],chainecouper,strlen(chainecouper));
    - Le père écrit un certain nombre de caractères qu'on suppose < TAILLE mais on envoit TAILLE caractères à p4 ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         }//Fin de la boucle while
         printf("FIN\n ");
     }
    Manque un return, la fermeture des pipes, le wait du père, l'exit des fils...

    Jc

  4. #4
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Mars 2011
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    Bonjour,

    je me demandais si tu as réussi a réaliser le programme? si oui ça serai trop sympa si vous me donniez quelque indications pouvant m'aider a le faire fonctionner.. Merci infiniment!

Discussions similaires

  1. Réponses: 0
    Dernier message: 15/10/2011, 21h12
  2. Executer commande dans un processus fils !
    Par jérôme.D dans le forum POSIX
    Réponses: 6
    Dernier message: 23/11/2006, 22h14
  3. Tuer processus fils
    Par lornak dans le forum POSIX
    Réponses: 7
    Dernier message: 29/05/2006, 10h00
  4. terminaison du processus fils
    Par zahira dans le forum POSIX
    Réponses: 3
    Dernier message: 08/04/2006, 13h35
  5. Partage d'une variable entre les processus fils
    Par Mehdi Feki dans le forum Linux
    Réponses: 7
    Dernier message: 09/01/2005, 13h34

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