Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

problème avec les threads

8 réponses
Avatar
Paul
bonjour,

je suis assez d=E9butant en perl, et j'ai un probleme avec un script que
j'esasye de faire. C'est vraiment difficil pour moi d'expliquer mon
probleme, et je vais faire de mon mieux :

j'ai une variable, un hash

pour l'exemple : $hash->{'popo'} =3D "test";
ensuite je lance un premier thread, puis un second thread, puis un
troisieme.

chacun de ces 3 threads vont devoir acc=E8der =E0 mon hash, sans ordre pr=E9
cis (thread 3 peut etre avant le thread 1...) dans chaques threads,
j'arrive =E0 lire mon hash sans probleme apparent. (print $hash->{'popo'}
par exemple, et il m'affiche "test") par contre, si je fais dans le
thread 1:

$hash->{'popo'} =3D "coucou";

puis dans le thread 3 :
print $hash->{'popo'}

alors, s'affiche non pas "coucou", mais "test"

le probleme est toujours l=E0 si c'est dans thread 3 que je fais
$hash->{'popo'} =3D "coucou";
et dans thread 1
print $hash->{'popo'};

Aussi, j'ai essay=E9 de rendre mon hash accessible, avec=20
my $hash : shared; (comme indiqu=E9 dans la doc de
threads::shared). mais cela ne fonctionne toujours pas.

de plus, dans chacuns des threads, j'ai essay=E9 de faire un=20
print $hash, et alors, il m'affiche l'allocation m=E9moire de mon
hash, mais je suis tr=E8s surpris de ne pas avoir la m=EAme allocation m=E9
moire pour les 3 threads : par cons=E9quent, je pense que lorsque je
lance mes threads, il me cr=E9e une instance de mon hash. Est ce que je me
trompe ?

bon, je reste disponible pour donner plus d'infos, mais en tout cas,
j'ai vraiment besoin d'aide pour continuer mon script.

Merci de votre attention.

8 réponses

Avatar
Trognon Patrice
Hi,

Oui en effet, je suis tombé sur ce problème aussi et je ne suis
pas arrivé a le solutionner.

j'ai contourné le problème en passant en multi process et non
en multi-threads.

Des threads qui ne partagent pas un espace d'adressage des données
je ne vois pas en quoi ca ressemble a des threads !!!

Cordialement,

Patrice.


bonjour,

je suis assez débutant en perl, et j'ai un probleme avec un script que
j'esasye de faire. C'est vraiment difficil pour moi d'expliquer mon
probleme, et je vais faire de mon mieux :

j'ai une variable, un hash

pour l'exemple : $hash->{'popo'} = "test";
ensuite je lance un premier thread, puis un second thread, puis un
troisieme.

chacun de ces 3 threads vont devoir accèder à mon hash, sans ordre pré
cis (thread 3 peut etre avant le thread 1...) dans chaques threads,
j'arrive à lire mon hash sans probleme apparent. (print $hash->{'popo'}
par exemple, et il m'affiche "test") par contre, si je fais dans le
thread 1:

$hash->{'popo'} = "coucou";

puis dans le thread 3 :
print $hash->{'popo'}

alors, s'affiche non pas "coucou", mais "test"

le probleme est toujours là si c'est dans thread 3 que je fais
$hash->{'popo'} = "coucou";
et dans thread 1
print $hash->{'popo'};

Aussi, j'ai essayé de rendre mon hash accessible, avec
my $hash : shared; (comme indiqué dans la doc de
threads::shared). mais cela ne fonctionne toujours pas.

de plus, dans chacuns des threads, j'ai essayé de faire un
print $hash, et alors, il m'affiche l'allocation mémoire de mon
hash, mais je suis très surpris de ne pas avoir la même allocation mé
moire pour les 3 threads : par conséquent, je pense que lorsque je
lance mes threads, il me crée une instance de mon hash. Est ce que je me
trompe ?

bon, je reste disponible pour donner plus d'infos, mais en tout cas,
j'ai vraiment besoin d'aide pour continuer mon script.

Merci de votre attention.


Avatar
Paul Gaborit
À (at) Tue, 5 Oct 2004 20:20:55 +0200,
Paul <ernond_paul_at_yahoo.fr> écrivait (wrote):
Aussi, j'ai essayé de rendre mon hash accessible, avec
my $hash : shared; (comme indiqué dans la doc de
threads::shared). mais cela ne fonctionne toujours pas.


Pour créer votre hashtable, essayez le code suivant :

use threads;
use threads::shared;

my $hash : shared;

$hash = &share({});

# la suite de votre script avec création des threads et utilisation
# parallèle de $hash *et* de son contenu...

Je n'ai pas testé mais cela devrait marcher. Sinon, il faudra faire des essais
supplémentaires... Tenez-nous au courant ;-)

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>

Avatar
Paul
Bonjour Paul Gaborit,

Je vous remercie pour votre aide.

J'ai donc essayé de faire $hash = &share({})
mais j'ai un probleme :
"thread failed to start: Invalid value for shared scalar at ic2.pl line
175."

la ligne 175 correspond à celle ci :
"delete($hash->{'folder'}->[$f]->{'record'}->[$r]->{'lastChecked'}->[0]);"

ok, je l'avoue, mon "hash de array de hash de array" est très compliqué
mais il proviens d'un XMLin avec un forcearray=>1

Je n'ai pas testé mais cela devrait marcher. Sinon, il faudra faire
des essais supplémentaires...


vous pouvez me donner une autre piste ?

Cordialement,




Le Wed, 06 Oct 2004 08:58:34 +0200
Paul Gaborit vous écriviez :


À (at) Tue, 5 Oct 2004 20:20:55 +0200,
Paul <ernond_paul_at_yahoo.fr> écrivait (wrote):
Aussi, j'ai essayé de rendre mon hash accessible, avec
my $hash : shared; (comme indiqué dans la doc de
threads::shared). mais cela ne fonctionne toujours pas.


Pour créer votre hashtable, essayez le code suivant :

use threads;
use threads::shared;

my $hash : shared;

$hash = &share({});

# la suite de votre script avec création des threads et
utilisation# parallèle de $hash *et* de son contenu...

Je n'ai pas testé mais cela devrait marcher. Sinon, il faudra faire
des essais supplémentaires... Tenez-nous au courant ;-)

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>



Avatar
Patrice Auffret
On Wed, 6 Oct 2004 21:37:25 +0200
Paul <ernond_paul_at_yahoo.fr> wrote:
[..]
la ligne 175 correspond à celle ci :
"delete($hash->{'folder'}->[$f]->{'record'}->[$r]->{'lastChecked'}->[0]);"
[..]


Tu fait un delete sur un element d'un tableau.

Et ca se fait pas. Ce n'est pas une hash ;)

Maintenant, si tu dois avoir des structures de données aussi compliquées,
tu peux peut-etre voir à utiliser du Perl objet pour grandement simplifier
les choses.

Avatar
Patrice Auffret
On Thu, 7 Oct 2004 09:28:45 +0200
Patrice Auffret wrote:
[..]
Tu fait un delete sur un element d'un tableau.

Et ca se fait pas. Ce n'est pas une hash ;)
[..]


Oulala, je dis une grosse bétise ;) bien sur qu'on peut
delete un élément d'un tableau.

Ce qu'il faut retenir de ce que j'ai dit c'est juste qu'il
vaut mieux utiliser de l'objet pour des structures aussi
compliquées.

Avatar
Paul Gaborit
À (at) Wed, 6 Oct 2004 21:37:25 +0200,
Paul <ernond_paul_at_yahoo.fr> écrivait (wrote):
J'ai donc essayé de faire $hash = &share({})
mais j'ai un probleme :
"thread failed to start: Invalid value for shared scalar at ic2.pl line
175."

la ligne 175 correspond à celle ci :
"delete($hash->{'folder'}->[$f]->{'record'}->[$r]->{'lastChecked'}->[0]);"

ok, je l'avoue, mon "hash de array de hash de array" est très compliqué
mais il proviens d'un XMLin avec un forcearray=>1


Ce qu'il faut bien comprendre, c'est que tous les objets référencés à partir de
la racine de votre structure partagée doivent eux-même être partagés.

Donc dans votre exemple, pour créer une telle structure, il vous faut passer
par :

my $hash : shared;

$hash = &share({});
$hash->{folder} = &share([]);
$hash->{folder}[$f] = &share({});
$hash->{folder}[$f]{record} = &share([]);
$hash->{folder}[$f]{record}[$r] = &share({});
$hash->{folder}[$f]{record}[$r]{lastChecked} = &share([]);
$hash->{folder}[$f]{record}[$r]{lastChecked}[0] = 12345;
delete($hash->{folder}[$f]{record}[$r]{lastChecked}[0);

Si vous ne faites pas cela, toute affectation d'une valeur non partagée dans
une variable partagée échoue avec le message 'invalid value for shared
scalar...'. En particulier l'autovivification ne peut pas fonctionner sur une
structure partagée. C'est peut-être la cause de votre erreur en ligne 175
(l'un des champs n'existent pas). Ajoutez donc un test d'existence avec le
'delete' :

if (exists $hash->{folder}[$f]{record}[$r]{lastChecked}[0]) {
delete $hash->{folder}[$f]{record}[$r]{lastChecked}[0];
}

PS: Quelle version de perl utilisez-vous ?

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>

Avatar
Paul
ce que vous dite ne me semble pas illogique. il me faut un peu de temps
et je testerais un peu plus. car ce soir, j'ai aps du tout la tête à
faire du Perl.

sinon :
This is perl, v5.8.3 built for i386-linux-thread-multi



Le Thu, 07 Oct 2004 14:52:26 +0200
Paul Gaborit vous écriviez :


À (at) Wed, 6 Oct 2004 21:37:25 +0200,
Paul <ernond_paul_at_yahoo.fr> écrivait (wrote):
J'ai donc essayé de faire $hash = &share({})
mais j'ai un probleme :
"thread failed to start: Invalid value for shared scalar at ic2.pl
line 175."

la ligne 175 correspond à celle ci :
"delete($hash->{'folder'}->[$f]->{'record'}->[$r]->{'lastChecked'}-
[0]);"


ok, je l'avoue, mon "hash de array de hash de array" est très
compliquémais il proviens d'un XMLin avec un forcearray=>1


Ce qu'il faut bien comprendre, c'est que tous les objets référencés à
partir de la racine de votre structure partagée doivent eux-même êt re
partagés.

Donc dans votre exemple, pour créer une telle structure, il vous faut
passer par :

my $hash : shared;

$hash = &share({});
$hash->{folder} = &share([]);
$hash->{folder}[$f] = &share({});
$hash->{folder}[$f]{record} = &share([]);
$hash->{folder}[$f]{record}[$r] = &share({});
$hash->{folder}[$f]{record}[$r]{lastChecked} = &share([]);
$hash->{folder}[$f]{record}[$r]{lastChecked}[0] = 12345;
delete($hash->{folder}[$f]{record}[$r]{lastChecked}[0);

Si vous ne faites pas cela, toute affectation d'une valeur non partagé
e dans une variable partagée échoue avec le message 'invalid value for
shared scalar...'. En particulier l'autovivification ne peut pas
fonctionner sur une structure partagée. C'est peut-être la cause de
votre erreur en ligne 175(l'un des champs n'existent pas). Ajoutez
donc un test d'existence avec le'delete' :

if (exists $hash->{folder}[$f]{record}[$r]{lastChecked}[0]) {
delete $hash->{folder}[$f]{record}[$r]{lastChecked}[0];
}

PS: Quelle version de perl utilisez-vous ?

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>




Avatar
Paul Gaborit
À (at) Thu, 7 Oct 2004 19:22:26 +0200,
Paul <ernond_paul_at_yahoo.fr> écrivait (wrote):
sinon :
This is perl, v5.8.3 built for i386-linux-thread-multi


C'est une version que je n'ai pas testée. Je suis passé directement de 5.8.0 à
5.8.4 et finalement 5.8.5. Je sais qu'il y a eu pas mal de corrections sur le
support des threads entre 5.8.0 et 5.8.5. Je ne peux que vous conseiller de
passer à la version 5.8.5 même si ce n'est pas cela qui corrigera votre bug.

Extrait de perldelta (pour la 5.8.5) :

Thread creation time could vary wildly between identical runs. This was
caused by a poor hashing algorithm in the thread cloning routines, which
has now been fixed.

--
Paul Gaborit - <http://www.enstimac.fr/~gaborit/>
Perl en français - <http://www.enstimac.fr/Perl/>