Background
Threads in Perl emerged in response to the need for concurrent computations and parallel work with resources in multitasking applications. The standardized threads module has been part of Perl since version 5.8, gradually evolving from experiments with ithreads to the universal threads::shared.
Problem
The first issue is that Perl does not support threads natively, as languages like Java do. Threads in Perl operate by copying the stack and data of each thread, which incurs overhead and makes it impossible to work directly with global variables (except for variables with special binding through threads::shared). Additionally, Perl does not guarantee independent operation of threads when writing data simultaneously without explicit synchronization.
Solution
To organize threads, the threads module is used along with the additional threads::shared module for data exchange between threads. Ensuring synchronization and data integrity falls on the developer, often through the use of locks.
Code example:
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 ";
Key features:
Is it possible to use any global variables without threads::shared and expect that threads will see each other's changes?
No. Global variables are copied into each thread individually. For sharing, only through threads::shared or other IPC (inter-process communication).
Is it allowed to run fork and threads in the same Perl script?
It is not recommended to mix fork and threads, as this leads to unpredictable bugs and unstable behavior. Perl officially warns against using these techniques simultaneously.
Can complex data structures be passed between threads through standard references?
No. Perl does not automatically copy recursively nested structures, and such attempts lead to errors or non-intuitive results. Deep copying and the use of shared resources would be required for that.
A developer created a simple queue through an array that was updated concurrently from multiple threads without threads::shared. Data often became corrupted, leading to incorrect program results.
Pros:
Cons:
Using threads::shared with locks, the entire queue was declared as shared, with synchronization occurring through locks. The program ran stably, even under heavy load.
Pros:
Cons: