Perl中的线程:分离顺序()



我正在尝试了解Perl对线程的使用。阅读文档时,我发现了以下代码:

use threads;
my $thr = threads->create(&sub1);   # Spawn the thread
$thr->detach();   # Now we officially don't care any more
sleep(15);        # Let thread run for awhile
sub sub1 {
my $count = 0;
while (1) {
$count++;
print("$count is $countn");
sleep(1);
}
}

目标似乎是创建一个运行sub1 15秒的线程,同时打印一些字符串。然而,我想我不明白节目结束时发生了什么。

首先,detach()定义如下:

一旦线程被分离,它将运行直到它完成;然后是Perl之后会自动清理。

但是,子程序什么时候结束?while(1)永远不会结束。我也没有在sleep()中找到任何信息,它会导致循环中断。最重要的是,从我们分离的那一点开始,我们"等待脚本完成,然后清理它"15秒,所以如果我们等待子例程完成,为什么我们在主脚本中需要sleep()?这个职位对我来说很尴尬;这表明主程序睡眠15秒。但这有什么意义呢?主程序(线程?)在子线程保持运行的同时休眠,但子程序是如何终止的?

我想这个想法是在sleep-ing完成后,子程序结束,之后我们可以分离/清理。但这在句法上是如何清晰的呢?在睡眠的定义中,哪里说sleep终止了一个子例程(以及为什么),它如何知道在有多个线程的情况下终止哪一个子例程?

程序结束时,所有线程都结束。程序在主线程结束时结束。主线程中的sleep只是使程序保持短时间运行,之后主线程(因此程序,因此所有创建的线程)也结束。

那么detach怎么了?它只是说"我永远不会加入这个线程,我不在乎它会返回什么"。如果没有detach线程或join线程,程序结束时会收到警告。

detach线程意味着"我不再在乎了",这实际上意味着当您的进程退出时,线程将出错并终止。

实际上,我认为您从来都不想在perl中分离线程,只需在代码末尾添加一个join,这样它就可以干净地退出,并通过信号量或Thread::Queue发出信号来终止。

$_ -> join for threads -> list; 

会成功的。

在我看来,那个代码示例是个糟糕的示例。对于sleep来说,这简直是一团糟,所以一个分离的线程有机会完成,而你只需要join就可以知道它已经完成了。perl线程尤其如此,假设它们是轻量级的是欺骗性的,因此可以很容易地启动(以及detached)。如果您的派生次数足够多,以至于join处理它们的开销太高,那么您使用perl线程是错误的,可能应该使用fork

你说得很对——线程永远不会终止,所以你的代码总是有一个"脏"出口。

所以我会重写:

#!/usr/bin/perl
use strict;
use warnings;
use threads;
use threads::shared;
my $run : shared;
$run = 1;
sub sub1 {
my $count = 0;
while ($run) {
$count++;
print("$count is $countn");
sleep(1);
}
print "Terminatingn";
}

my $thr = threads->create( &sub1 );    # Spawn the thread
sleep(15);                               # Let thread run for awhile
$run = 0;
$thr->join;

通过这种方式,main向线程发出信号说"我完成了",并等待它完成当前循环。

最新更新