[C] Fork et Pipe

Fork et Pipe [C] - C - Programmation

Marsh Posté le 06-06-2009 à 11:50:33    

Bonjour à tous =)
 
Je dois réaliser un programme en C dont le but est de créer (N-1) fils issus d'un même père et dont chacun d'entre eux est relié par un tube.
Le père transmet un entier au premier fils et cet entier devra parcourir tous les fils ensuite grâce aux tubes en l'incrémentant dans chaque passage dans un fils.
 
Voici le programme qui créé un nombre x de processus  :
 
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
 

Code :
  1. int main(){
  2. int num_proc = 0;
  3. int nb_proc = 10;
  4. int essai;
  5. pid_t pid;
  6. do{
  7.  essai=0;
  8.  do{
  9.   pid = fork();
  10.   essai ++;
  11.  }while ((pid == -1)&&(essai<100));
  12.  if(essai!=100 && pid!=0){
  13.   num_proc++;
  14.  }
  15.  else if(pid==0){
  16.   printf("num_proc : %d \n",num_proc);
  17.   pid = getpid();
  18.   _exit(pid);
  19.  }
  20. }while ((pid!=0) && (num_proc<=nb_proc));
  21. }


 
Comment rajouter les pipes dans ce programme ? Les documentations que j'ai lu,  je n'ai pas comprit grand chose ...

Reply

Marsh Posté le 06-06-2009 à 11:50:33   

Reply

Marsh Posté le 06-06-2009 à 15:50:48    

Salut
 
 
man 2 pipe

Citation :

EXAMPLE
       The following program creates a pipe, and then fork(2)s to create a child process; the child
       inherits  a  duplicate  set  of  file  descriptors  that  refer to the same pipe.  After the
       fork(2), each process closes the  descriptors  that  it  doesn’t  need  for  the  pipe  (see
       pipe(7)).   The  parent then writes the string contained in the program’s command-line argu‐
       ment to the pipe, and the child reads this string a byte at a time from the pipe and  echoes
       it on standard output.

Code :
  1. #include <sys/wait.h>
  2. #include <assert.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <string.h>
  7. int main(int argc, char *argv[])
  8. {
  9.             int pipefd[2];
  10.             pid_t cpid;
  11.             char buf;
  12.             assert(argc == 2);
  13.             if (pipe(pipefd) == -1) {
  14.                  perror("pipe";);
  15.                  exit(EXIT_FAILURE);
  16.            }
  17.            cpid = fork();
  18.            if (cpid == -1) {
  19.                perror("fork";);
  20.                exit(EXIT_FAILURE);
  21.            }
  22.            if (cpid == 0) {    /* Child reads from pipe */
  23.                close(pipefd[1]);          /* Close unused write end */
  24.                while (read(pipefd[0], &buf, 1) > 0)
  25.                    write(STDOUT_FILENO, &buf, 1);
  26.                write(STDOUT_FILENO, "n", 1);
  27.                close(pipefd[0]);
  28.                _exit(EXIT_SUCCESS);
  29.            } else {            /* Parent writes argv[1] to pipe */
  30.                close(pipefd[0]);          /* Close unused read end */
  31.                write(pipefd[1], argv[1], strlen(argv[1]));
  32.                close(pipefd[1]);          /* Reader will see EOF */
  33.                wait(NULL);                /* Wait for child */
  34.                exit(EXIT_SUCCESS);
  35.            }
  36.        }




Dis nous précisément ce que tu ne comprends pas, difficile d'aider quelqu'un qui dit juste qu'il n'y arrive pas.


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 07-06-2009 à 10:49:45    

apaachee a écrit :


Comment rajouter les pipes dans ce programme ? Les documentations que j'ai lu,  je n'ai pas comprit grand chose ...


Il y a 2 façons de faire un pipe
1) un fichier pipe sur disque puis un processus y écrit et un autre le lit
2) un pipe entièrement en mémoire. Cette 2° façon est limitée aux seuls processus liés père/fils (mais c'est possible puisque c'est ton cas)
 
Donc à toi de choisir quelle façon faire puisque t'as possibilité de faire les deux. Perso je choisirais la 2° puisque ça m'évite de m'embêter à créer un fichier.
 
Donc la technique de base pour communiquer entre un père et son fils
1) le programme commence par créer le pipe mémoire grace à la fonction pipe() à laquelle il passe un int tab[2]
Cette fonction se charge de créer le pipe et d'allouer tab[0] comme point de lecture et tab[1] comme point d'écriture
2) le programme génère son fils grace à fork(). Le fils reçoit donc une copie de la mémoire du père donc de tab
3) le processus qui devra écrire ferme tab[0] et celui qui devra lire ferme tab[1]
4) celui qui écrit fait du write(tab[1], zone, nb_octets) et celui qui doit lire fait du read(tab[0], zone, nb_octets)
5) une fois que c'est fini, chaque processus ferme son tab[x] utilisé
 
Pour toi qui doit faire "n" fils, t'auras besoin de "n" tab[2] donc int tab[n][2]. Ca risque de devenir galère. C'est pourquoi je te conseillerais de définir un type t_pipe

Code :
  1. typedef struct {
  2.     int cote[2];
  3. } t_pipe;


 
Comme ça, tu n'as plus qu'à créer un t_pipe pipe[n] puis chaque fils "x" ira lire dans pipe[x - 1].cote[0] et écrire dans pipe[x].cote[1] (enfin j'espère que tu vois le principe)
 
Petite doc sur les pipes: http://fr.lang.free.fr/cours/Processus_Csyst_v1.0.pdf


Message édité par Sve@r le 07-06-2009 à 10:57:29

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed