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.
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" ;
}
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
 
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
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.

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