Perl中的线程:detach()

时间:2017-02-13 16:17:13

标签: multithreading perl sleep

我正试图进入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终止子程序(以及为什么),如果有多个线程,它如何知道终止哪一个?

2 个答案:

答案 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

通过这种方式,你的主要信号表示线程说“我已经完成”并等待它完成它的当前循环。