在Perl中进行多线程处理时应该注意哪些模块?

Dre*_*ens 7 perl multithreading

在Perl中进行多线程处理时应该注意哪些模块?

我想做一些相当低的性能; 我想线程是同时运行多个工作者,每个人都在不同的时间内睡觉.

Don*_*ron 9

您可能不希望多线程有很多原因.但是,如果您确实想要多线程,则以下代码可能是一个有用的示例.它创建了许多作业,将它们放在一个线程安全的队列中,然后启动一些线程从队列中拉出作业并完成它们.每个线程都会循环从队列中拉出作业,直到它看不到更多的作业.程序等待所有线程完成,然后打印它在作业上花费的总时间.

#!/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.";
}
Run Code Online (Sandbox Code Playgroud)


fri*_*edo 7

如果性能不是一个大问题,那么fork多个进程可能比处理线程容易得多.我经常使用Parallel :: ForkManager,它非常简单,但非常擅长它的功能.


mob*_*mob 7

最新版本的Perl具有线程支持.运行perl -V:usethreads以查看它是否在您的系统中可用.

$ perl -V:usethreads
usethreads='define'
Run Code Online (Sandbox Code Playgroud)

perldoc threads 给出了很好的使用它们的介绍.


der*_*ert 5

听起来你不需要先发制人的多线程; 在这种情况下,看看POE的合作模式.由于您的代码在您决定时只会产生其他线程,并且您一次只能运行一个线程,因此开发和调试将变得更加容易.

  • 值得注意的是,虽然POE不会隐式支持多线程或多处理,但是`POE :: Wheel :: Run`允许您在分叉进程中运行一段代码,将其I/O和退出状态转换为POE事件.有时包围阻塞代码是非常有用的. (3认同)