我正试图进入Perl对线程的使用。阅读documentation我遇到了以下代码:
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 $count\n");
sleep(1);
}
}
似乎目标是创建一个运行sub1的线程15秒,同时打印一些字符串。但是,我不认为我理解程序结束时会发生什么。
首先,detach()
定义如下:
一旦线程被分离,它将一直运行直到它完成;那么Perl 将自动清理。
然而,子程序何时完成? while(1)
永远不会结束。我也没有在sleep()
中找到导致打破循环的任何信息。最重要的是,从我们分离点开始,我们“等待脚本完成然后将其清理”15秒,所以如果我们等待子程序完成,我们为什么要这样做在主脚本中需要sleep()
吗?这个职位对我来说很尴尬;它表明主程序睡眠时间为15秒。但那有什么意义呢?主程序(线程?)在子线程继续运行时休眠,但子程序如何终止?
我想这个想法是在完成sleep
之后,子程序结束,之后我们可以分离/清理。但这在句法上是如何清晰的?在sleep的定义中,它表示sleep
终止子程序(以及为什么),如果有多个线程,它如何知道终止哪一个?
答案 0 :(得分:3)
所有线程在程序结束时结束。程序在主线程结束时结束。主线程中的sleep
只是让程序保持运行一段时间,之后主线程(因此程序,因此所有创建的线程)也结束。
那么detach
会怎么样?它只是说“我永远不会打扰加入这个线程,我不关心它返回什么”。如果你没有detach
一个主题或join
,那么当程序结束时你会收到警告。
答案 1 :(得分:2)
detach
一个线程意味着“我不再关心了”,这实际上意味着当你的进程退出时,线程会出错并终止。
实际上 - 我认为您不想在perl中分离线程 - 只需在代码末尾添加join
,这样它就可以干净地退出,并通过信号量或{发信号通知} {1}}以便终止。
Thread::Queue
会做的伎俩。
在我看来,那个代码示例是一个不好的例子。 $_ -> join for threads -> list;
只是简单的混乱,所以当你可以sleep
和知道它已经完成时,一个分离的线程有机会完成。对于join
线程尤其如此,假设它们是轻量级的,它们具有欺骗性,因此可以简单地启动(和perl
)。如果你产生足够的detached
它们的开销太高,那么你使用perl线程是错误的,而且可能应该join
。
你说得对 - 线程永远不会终止,所以你的代码总是有一个'脏'退出。
所以我改写了:
fork
通过这种方式,你的主要信号表示线程说“我已经完成”并等待它完成它的当前循环。