Bonjour
Je cherche à mettre en parallèle le téléchargement simultané de pages web avec analyse en direct et je me retrouve confronté à un problème de communication entre processus.
En gros j'ai une liste de N sites à visiter, pour ce je fais M forks consécutifs (N > M), et je souhaite passer la liste des sites dans un fifo, et chacun des fils viendrait ensuite piocher dans le fifo. Lorsqu'un fils a terminé, il viendrait lire une nouvelle adresse dans le fifo, si le fifo est vide, alors le fils meurt.
J'ai tenté le code suivant mais le souci est que seul l'ainé des fils vient lire dans le fifo, les autres fils meurent aussitôt.
produit la sortie suivante :
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 #!/usr/bin/perl -w use strict ; use warnings ; my $nb_fork = '3' ; # Nombre de fois que le script sera dupliqué => nbre de connections simultanées my $pid = '-1' ; my $i = '0' ; my @liste = ('eins', 'zwei', 'drei', 'vier', 'funf', 'sechs', 'sieben', 'acht', 'neun', 'zehn') ; pipe (EN, SO) ; # appel à pipe ou tube nommé : même résultat while ($pid != '0' and $i < $nb_fork) { $pid = fork ; $i++ ; } if ($pid == '0') # L'un des processus fils { $i-- ; close (SO) ; open (ENTREE, "<&EN") ; # J'ai tenté de dupliqué le descripteur de fichier mais sans changement print "Ici on est dans le fils et \$i vaut $i\n" ; while (my $var = <ENTREE>) { print "Le fils n°$i s'occupe de $var" ; sleep (1) ; } print " --> Sortie du fils n°$i\n" ; close ENTREE ; close EN ; } else # Le processus père { close EN ; open (SORTIE, ">&SO") ; foreach my $site (@liste) { print SORTIE "$site\n" ; } print " --> Le père attend la fin des fils\n" ; close SORTIE ; close SO ; do {} while (wait () >= '0') ; print " --> Sortie du père\n" ; }
On voit bien que le cadet et le benjamin quittent aussitôt car semblent incapables de lire dans le tube, seul l'ainé effectue le travail.
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 Ici on est dans le fils et $i vaut 0 Ici on est dans le fils et $i vaut 1 Ici on est dans le fils et $i vaut 2 --> Le père attend la fin des fils Le fils n°0 s'occupe de eins --> Sortie du fils n°1 --> Sortie du fils n°2 Le fils n°0 s'occupe de zwei Le fils n°0 s'occupe de drei Le fils n°0 s'occupe de vier Le fils n°0 s'occupe de funf Le fils n°0 s'occupe de sechs Le fils n°0 s'occupe de sieben Le fils n°0 s'occupe de acht Le fils n°0 s'occupe de neun Le fils n°0 s'occupe de zehn --> Sortie du fils n°0 --> Sortie du père
J'ai tenté avec et sans duplication des descripteurs de fichiers tant en entrée qu'en sortie, tant avec pipe qu'avec un tube nommé.
Quelqu'un saurait-il me dire comment faire en sorte que plusieurs fils viennent lire dans un même tube ??? D'après les infos que j'ai trouvé, c'est possible mais rien qui ne dise comment ...
Merci d'avance
Yann
Partager