Bonjour,
Je suis en train d'essayer d'écrire un petit script qui distribuerait l'exécution de calculs sur plusieurs threads via perl. L'idée est que chaque thread appelle le code de calcul (fortran). Les fichiers à traiter sont répartis dans des répertoires et ilfaut que les threads se baladent de répertoire en répertoire, exécute le calcule, puis passe au suivant, jusqu'à épuisement des répertoires. Je suis très très débutant avec les threads. À ce que j'ai compris, c'est un cas de gestion par "pool". Le nombre de threads est fixé à 7 et il y a environ 30 répertoires à traiter une dizaine de fois - environ 300 en tout. Un calcul fortran dure dans les 2500 secondes - d'où le désir de paralléliser tout ça (outre que c'est fun d'apprendre). Pour le moment, j'en suis à l'état ci-dessous, qui est très préliminaire et ne contient pas encore l'appelle system ('calcul_fortran') qui va bien. Mon problème est que les threads ne se promènent qu'une fois dans une première série de répertoire, et ne passent pas par chacun d'entre eux...
Toute suggestion serait la bienvenue !
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 #!/usr/bin/perl -w use strict; use warnings; use Thread::Pool; my %resolved : shared; use Cwd; my @replist;#liste des répertoires à traiter sub do {#fonction bidon pour vérifier que le thread est passé dans le répertoire : devra appeler le code fortran à terme chdir $_[0]; system ('touch thread_'. Thread::Pool->jobid .'_was_here'); chdir '..'; } my $rep; foreach $rep ( <*> )#création de la liste des répertoires à traiter { next if( ! -d $rep );#si c'est un répertoire next if( ! -f $rep.'/TITI6');#il faut un fichier de positions push(@replist, $rep) if(! -f $rep.'/INTERFERENCE.csv');#si pas de fichier INTERFERENCE déjà présent } if (1 < @replist){#il y a des répertoires à traiter : il faut les distribuer entre les threads puis exécuter #Il faut répartir sur au plus 8 threads my $pool = Thread::Pool->new( { workers => 8, do => \&do, monitor => \&monitor, } ); while (@replist){ $pool->add( pop @replist ) ; } $pool->join(); } else{ if(1 == @replist){#il n'y a qu'un fichier à traiter } }
Merci beaucoup,
Marc
Partager