如何在perl中运行并发线程?

use*_*757 9 perl multithreading

以下似乎不像我预期的那样在并发线程中运行,而是每个进程阻塞直到它完成:

my @arr = (1,2,3,4);
foreach (@arr) {
   threads->new(\&doSomething, $_)->join;
}

sub doSomething {
    my $thread = shift;
    print "thread $thread\n";
    sleep(5);
}
Run Code Online (Sandbox Code Playgroud)

换句话说,它似乎执行与非线程版本相同:

my @arr = (1,2,3,4);
foreach (@arr) {
   doSomething($_);
}
Run Code Online (Sandbox Code Playgroud)

我正在运行ActivePerl v5.10.1 mswin32-x86-multi-thread

如何在perl中运行并发线程?

Dae*_*yth 13

perldoc threads.

问题是调用join()一个线程等待它完成.你想生成线程然后加入,而不是作为一个操作生成/加入.

进一步看看perldoc threads说:

threads->列表()

threads->列表(线程::所有)

threads->列表(线程运行::)

threads->列表(线程::加入)

如果没有参数(或使用threads :: all)并且在列表上下文中,则返回所有未连接的非分离线程对象的列表.在标量上下文中,返回相同的计数.

使用true参数(使用threads :: running),返回仍在运行的所有未连接,未分离的线程对象的列表.

使用false参数(使用threads :: joinable),返回已完成运行的所有未连接,未分离的线程对象的列表(即,对于 - > join()将不会阻塞).

您可以使用它来循环和列出线程,在可能的情况下加入,直到所有线程都完成(并且您可能需要一个上限来等待时间来杀死它们并中止)

  • 究竟.`join`是一个阻塞操作.但是,当主进程等待`join`返回时,已经生成的线程将继续运行.在这种情况下,如果您生成所有线程然后加入,则您希望第一次加入呼叫大约需要5秒,而所有其他加入呼叫都非常短. (4认同)

Ste*_*epp 13

你必须在之后加入它们,而不是在创建时加入它们:

my @arr = (1,2,3,4);
my @threads;
foreach (@arr) {
   push @threads, threads->new(\&doSomething, $_);
}
foreach (@threads) {
   $_->join();
}
Run Code Online (Sandbox Code Playgroud)