Salut!
J'ai un peu de mal à capter comment les tubes fonctionnent à cause des résultats aléatoires que je récupère... Je vous explique.
J'ai pour mission de récupérer la liste des fichiers d'un sous arbre à partir d'un point donné du disque.
Exemple : ./monprog repdepart
Lors du parcours de repdepart, le programme va, s'il tombe sur un repertoire à l'interieur de repdepart, lancer un processus fils avec l'appel fork();.
Les processus communiquent entre eux la liste des fichiers trouvés via UN tube.
Donc, le tube est crée par le programme principal. Premier fork() : si je suis le fils, je ferme le tube en lecture et je lance l'algoryhtme sur (repdepart,tube).
Si je suis le pere, je ferme le tube en ecriture et j'attends par un while (read ...) des informations de mon fiston.
Maintenant, si le fils, lorsqu'il parcoure la liste des fichiers, trouve un repertoire, il crée un fils avec (repdepart/reptrouvé,tube);
Ainsi de suite.
Le probleme est que quand le premier fils a fini son boulot, le pere considère que il n'y aura plus rien dans le tube et termine la boucle while(read...)
J'ai bien essayé de placer quelques wait(0);, avant la fermeture des tubes en ecriture par les fils (donc quand il ont fini) ou à d'autres endroits, ca ne marche pas.
Donc j'aimerais qu'on m'explique quelques trucs quand à ces histoires de tubes et fork. Parceque je comprends pas pourquoi le pere arrete de lire alors que l'un de ses sous fils a toujours un tube ouvert en mode ecriture.
L'algoryhtme en simplifié :
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 #include<iostream.h> #include"Liste.h" #include <stdio.h> #include <sys/types.h> #include <dirent.h> #include <sys/wait.h> #include <fstream.h> #include <sys/stat.h> void parcours(char * repertoire, int * tube) { cout<<"("<<getpid()<<")" << "Fonction parcours sur : " << repertoire << endl; char cheminfich [1024]; char liste[2048]; close(tube[0]); struct dirent *lecture; DIR *rep; pid_t pid; rep = opendir(repertoire); struct stat st; if (rep) { while (lecture = readdir(rep)) { //si c'est un fichier régulier, je l'ajoute à ma liste de fichiers spéaré par un caractere disons '|' //sinon si c'est un repertoire, je lance un fils { pid=fork(); if (pid==0) { parcours(cheminfich,tube); //cheminfich a déjà ete modifié et contiens bien le chemin vers le repertoire que l'on viens de trouver } } } } write(tube[1],liste,strlen(liste)+1); closedir(rep); } close(tube[1]); } int main (int argc, char * argv[]) { int tube[2]; char buffer[1024]; pid_t pid; if (argc!=2) { cout<<"("<<getpid()<<")"<<"Spécifiez un et un seul repertoire à analyser."<<endl; exit(-1); } if (pipe(tube)<0) { cout<<"("<<getpid()<<")"<<"Impossible d'ouvrir un tube de communication"<<endl; exit(-1); } pid=fork(); if (pid==0) { parcours(argv[1],tube); return 1;} else { close(tube[1]); while (read(tube[0],buffer, sizeof(buffer))>0) { //je gere mon message recu. } close(tube[0]); } wait(0); return 1; }
Partager