我对Perl线程相当新,所以我想知道在Perl中执行此操作的正确方法:
for $input (@inputs) {
push @threads, start_thread($input);
}
for $thread (@threads) {
wait_for_external_event();
$thread->kick_thread_out_of_loop();
$result = $thread->result();
print $result;
}
sub my_thread {
my $input = shift;
while(1) {
my $result = compute($best_result_so_far,$input);
if($result > $best_result_so_far) {
$best_result_so_far = $result;
}
}
# The thread got kicked out of the loop
return $best_result_so_far;
do_some_cleanup_that_is_slow();
exit thread;
}
我觉得将线程从计算循环中踢出来的方法是使用信号并在线程中有一个信号处理程序。但也许有更好的方法可以做到这一点。我需要一些关于如何实现这一点的帮助,特别是我如何返回$ best_result_so_far以及返回之后进行慢速清理。非常重要的是,我无需等待清理才能获得结果。
---编辑---
我查看了教程,我无法找到与正在运行的线程进行通信的示例(“join”仅执行死线程)。我可以从正在运行的线程中获取结果,类似于:
for $input (@inputs) {
push @threads, start_thread($input);
}
for $thread (@threads) {
wait_for_external_event();
$result = $thread->result();
$thread->kill("KILL");
print $result;
}
package ThreadObj;
sub my_thread {
my $self = shift;
my $input = shift;
local $SIG{KILL} = sub {
do_slow_cleanup();
threads->exit();
};
while(1) {
my $result = compute($best_result_so_far,$input);
if($result > $self->{'best_result_so_far'}) {
$self->{'best_result_so_far'} = $result;
}
}
}
sub result {
my $self = shift;
wait until (defined $self->{'best_result_so_far'});
return $self->{'best_result_so_far'};
}
答案 0 :(得分:1)
据我所知,无法从线程返回结果并将线程清理延迟到以后。
如果$best_result_so_far
在所有线程中都是通用的(IOW只有一个最佳结果),那么threads::shared
和信号量可能有所帮助(虽然性能成本)。有关一些不错的初学者示例,请参阅perldoc perlthrtut
。
感觉这个问题更适合基于事件的编程范例。可能Coro::AnyEvent
是这项工作的正确工具吗?
答案 1 :(得分:1)
我将使用一个或两个通用数据结构进行通信,其中每个线程使用其自己的唯一ID来访问共享哈希中的条目以存储其当前结果。使用第二个哈希,以相同的方式,作为一个标志向线程发信号通知它是时候退出 - 或者是一个共同的标量,以防所有线程必须同时退出。只要未设置标志,就可以循环,而不是无限循环。