如何在不终止整个程序的情况下立即结束 Perl 线程?

6

当我使用exitdie时,它会终止整个程序。

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

有什么想法吗?

请查看我的评论:https://dev59.com/kGvXa4cB1Zd3GeqPLavH#27690901 - Paolo Rovelli
3个回答

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

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

threads->exit()

If needed, a thread can be exited at any time by calling threads->exit(). This will cause the thread to return undef in a scalar context, or the empty list in a list context. When called from the main thread, this behaves the same as exit(0).


可能有一种方法可以实现即时终止(在Windows上对我无效):

use threads 'exit' => 'threads_only';

This globally overrides the default behavior of calling exit() inside a thread, and effectively causes such calls to behave the same as threads->exit() . In other words, with this setting, calling exit() causes only the thread to terminate. Because of its global effect, this setting should not be used inside modules or the like. The main thread is unaffected by this setting.

文档还提供了另一种方法,使用 set_thread_exit_only 方法(但在 Windows 上对我无效):
$thr->set_thread_exit_only(boolean)

This can be used to change the exit thread only behavior for a thread after it has been created. With a true argument, exit() will cause only the thread to exit. With a false argument, exit() will terminate the application. The main thread is unaffected by this call.


下面的示例使用一个kill 信号来终止$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!'

1
有没有可能完全终止线程?让它消失,停止占用我的CPU和RAM? - Saustin
是的,通过 detach。一旦线程完成,Perl 将进行必要的清理工作。 - user554546
1
我想立即停止线程。我应该使用外部方法(全局布尔值来告诉何时停止)吗?我认为那可能会起作用。 - Saustin
1
@Saustin:你可以尝试使用我在答案中更新的use threads 'exit' => 'threads_only'; - Zaid
1
它仍然做着同样的事情 - 我尝试了两种方法。我可能会继续使用全局布尔值。 - Saustin
@Saustin: 我用线程信号实现了它...正在更新我的答案。 - Zaid

3

如果你想杀死一个线程,你可以使用$thread->kill。如果你想让线程继续运行但不再与父线程相关,可以使用$thread->detachthreads->exit会导致当前线程退出;它不需要一个线程作为调用者。


0
错误信息告诉你$t->exit需要一个参数。尝试给它一个。(perldoc Threads似乎说不需要,但我不知道你使用的是哪个包。)

我正在使用线程。我尝试过了,没有用。我还用die做了这件事。 - Saustin
$t 是一个 Threads 对象吗?尝试打印 ref $t。在 foreach 循环中的表达式真的是 threads->list() 吗,还是 Threads->list() - Keith Thompson
那绝对不是问题。 - Saustin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接