What modules should I look at for doing multithreading in Perl?
I'm looking to do something fairly low performance; I want threads is to run multiple workers simultaneously, with each of them sleeping for varying amounts of time.
Creating Threads Like any other module, you need to tell Perl that you want to use it; use threads; imports all the pieces you need to create basic threads. The create() method takes a reference to a subroutine and creates a new thread that starts executing in the referenced subroutine.
Perl can do asynchronous programming with modules like IO::Async or Coro, but it's single threaded. You can compile Perl with threads, which provide multi-threaded computing.
For Windows you can run the program and then open task manager by pressing ctrl+shift+esc keys. Look for processes with a number in parentheses after the name: That is the number of tasks the program currently has active. Single-threaded programs won't have multiple tasks.
There are lots of reasons why you might not want to multithread. If you do want to multithread, however, the following code might serve as a helpful example. It creates a number of jobs, puts those in a thread-safe queue, then starts some threads that pull jobs from the queue and complete them. Each thread keeps pulling jobs from the queue in a loop until it sees no more jobs. The program waits for all the thread to finish and then prints the total time that it spent working on the jobs.
#!/usr/bin/perl
use threads;
use Thread::Queue;
use Modern::Perl;
my $queue= Thread::Queue->new;
my $thread_count= 4;
my $job_count= 10;
my $start_time= time;
my $max_job_time= 10;
# Come up with some jobs and put them in a thread-safe queue. Each job
# is a string with an id and a number of seconds to sleep. Jobs consist
# of sleeping for the specified number of seconds.
my @jobs= map {"$_," . (int(rand $max_job_time) + 1)} (1 .. $job_count);
$queue->enqueue(@jobs);
# List the jobs
say "Jobs IDs: ", join(", ", map {(split /,/, $_)[0]} @jobs);
# Start the threads
my @threads= map {threads->create(sub {function($_)})} (1 .. $thread_count);
# Wait for all the threads to complete their work
$_->join for (@threads);
# We're all done
say "All done! Total time: ", time - $start_time;
# Here's what each thread does. Each thread starts, then fetches jobs
# from the job queue until there are no more jobs in the queue. Then,
# the thread exists.
sub function {
my $thread_id= shift;
my ($job, $job_id, $seconds);
while($job= $queue->dequeue_nb) {
($job_id, $seconds)= split /,/, $job;
say "Thread $thread_id starting on job $job_id ",
"(job will take $seconds seconds).";
sleep $seconds;
say "Thread $thread_id done with job $job_id.";
}
say "No more jobs for thread $thread_id; thread exiting.";
}
Most recent versions of Perl have threading support. Run perl -V:usethreads
to see if it is available in your system.
$ perl -V:usethreads
usethreads='define'
perldoc threads
gives a pretty good introduction to using them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With