Historique de la question
Les threads (threads) sont apparus dans Perl en réponse à la nécessité d'organiser des calculs concurrents et un travail parallèle avec des ressources dans des programmes multitâches. Le module standardisé threads fait partie intégrante de Perl depuis la version 5.8, passant progressivement des expériences avec ithreads à un threads::shared universel.
Problème
La première complexité est que Perl ne prend pas en charge les threads nativement, comme c'est le cas dans des langages comme Java. Les threads en Perl fonctionnent grâce à la copie de la pile et des données de chaque thread, ce qui crée une surcharge et rend impossible le travail direct avec des variables globales (à l'exception des variables avec liaison spéciale via threads::shared). De plus, Perl ne garantit pas le fonctionnement indépendant des threads lors de l'écriture simultanée de données sans synchronisation explicite.
Solution
Pour organiser les threads, on utilise le module threads et un module complémentaire threads::shared pour l'échange de données entre les threads. L'assurance de la synchronisation et de l'intégrité des données incombe au développeur, souvent par le biais de l'utilisation de locks.
Exemple de code :
use threads; use threads::shared; my $counter :shared = 0; sub increment { lock($counter); $counter++; } my @threads; for (1..10) { push @threads, threads->create(\&increment); } $_->join for @threads; print "Counter: $counter ";
Caractéristiques clés :
Est-il possible d'utiliser n'importe quelles variables globales sans threads::shared et de s'attendre à ce que les threads voient les modifications des uns et des autres ?
Non. Les variables globales sont copiées dans chaque thread individuellement. Pour les échanges — uniquement via threads::shared ou d'autres moyens IPC (entre processus).
Est-il permis d'exécuter fork et threads dans un même script Perl ?
Il n'est pas recommandé de mélanger fork et threads, car cela entraîne des bugs imprévisibles et un comportement instable. Perl avertit officiellement contre l'utilisation simultanée de ces techniques.
Peut-on transmettre des structures de données complexes entre threads via des références standards ?
Non. Perl ne copie pas automatiquement les structures imbriquées de manière récursive, et de telles tentatives entraînent des erreurs ou des résultats non intuitifs. Pour cela, une copie profonde et l'utilisation de ressources partagées seront nécessaires.
Un développeur a créé une simple file d'attente via un tableau, mise à jour simultanément par plusieurs threads sans threads::shared. Les données se corrompaient souvent, entraînant des résultats incorrects du programme.
Avantages :
Inconvénients :
Utilisation de threads::shared avec des locks, toute la file d'attente a été déclarée comme partagée, la synchronisation se faisait via lock. Le programme fonctionnait sans accroc, même sous une forte charge.
Avantages :
Inconvénients :