如何在不杀死整个程序的情况下立即杀死Perl线程?

Sau*_*tin 5 perl multithreading

当我使用exit或时die,它会杀死整个程序.

foreach my $t (threads->list())
{
    $t->exit;
    $count++;
}

Usage: threads->exit(status) at main.pl line 265
Perl exited with active threads:
        9 running and unjoined
        0 finished and unjoined
        0 running and detached
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

Zai*_*aid 7

要忽略正在执行的线程,返回控制并丢弃它可能输出的任何内容,正确的使用方法是detach,而不是exit.

请参阅perldoc perlthrtut- 忽略线程.


perldoc threads 解释为什么代码退出:

threads->exit()
Run Code Online (Sandbox Code Playgroud)

如果需要,可以随时通过调用退出一个线程 threads->exit().这将导致线程在标量上下文中返回undef,或在列表上下文中返回空列表.从线程调用时,其行为与...相同exit(0).


可能有一种方法可以实现即时终止(在Windows上对我不起作用):

use threads 'exit' => 'threads_only';
Run Code Online (Sandbox Code Playgroud)

这全局覆盖了调用exit() 线程内部的默认行为,并有效地使这些调用的行为与...相同threads->exit().换句话说,使用此设置,调用 exit()仅导致线程终止.由于其全局效果,不应在模块等内部使用此设置.主线程不受此设置的影响.

该文档还提出了另一种方法,使用该set_thread_exit_only方法(再次,在Windows上对我不起作用):

$thr->set_thread_exit_only(boolean)
Run Code Online (Sandbox Code Playgroud)

这可以用于在创建线程后更改线程的仅退出线程行为.使用true参数,exit()将仅导致线程退出.使用false参数,exit()将终止应用程序.主线程不受此调用的影响.


下面的例子使用了一个杀的信号来终止$unwanted线程:

use strict;
use warnings;
use threads;

my $unwanted = threads->create( sub {
                                      local $SIG{KILL} = sub { threads->exit };
                                      sleep 5;
                                      print "Don't print me!\n";
                                    } );

my $valid    = threads->create( sub {
                                      sleep 2;
                                      print "This will print!\n";
                                    } );

$unwanted->kill('KILL')->detach;   # Kills $thr, cleans up

$valid->join;                 # sleep 2, 'This will print!'
Run Code Online (Sandbox Code Playgroud)