实际上,在 Perl 中杀死线程的方法很少,具体取决于您想要实现的目标。
我们以下面的代码为例:
use strict;
use warnings;
use threads;
use Thread::Queue;
# Create the shared queue (used by the threads):
my $queue = Thread::Queue->new();
sub main {
# Initialise the shared queue:
$queue->enqueue("A", "B", "C", "D", "E", "F");
print "Total number of items: " . $queue->pending() . "\n";
$queue->end(); # signal that there is no more work to be sent...
# Create 3 threads:
threads->create('do') for ( 0..2 );
print "Number of current threads: " . threads->list() . "\n";
foreach my $thread ( threads->list() ) { # for each thread...
$thread->join(); # wait the thread to finish all its work...
print "Number of items in the queue: " . $queue->pending() . "\n" if defined $queue->pending();
print "Number of current threads: " . threads->list() . "\n";
}
}
sub do {
# Retrieve the current thread ID:
my $threadID = threads->self()->tid();
# Setup the thread's kill signal handler:
local $SIG{KILL} = sub { threads->exit() };
while ( defined (my $item = $queue->dequeue()) ) { # for each element in the queue...
print "(Thread-" . $threadID . "): Do something with item '$item'...\n";
sleep 1 + $threadID;
print "(Thread-" . $threadID . "): Finished to use item '$item'...\n";
}
}
main();
上面的代码产生了 3 个线程,每个线程将获取并处理共享队列的一个元素,直到队列为空。
在这种情况下,由于我们声明将不再向队列添加元素(即$queue->end()),一旦线程处理完队列的所有元素,它们将被加入(到主线程)。实际上,使用$thread->join()我们是在告诉 main 等待$thread加入。
如果我们省略声明$queue->end(),线程将不会加入主线程,而是等待队列的新元素。
现在,如果我们想杀死线程,我们有两种选择:杀死线程但让它们先完成它们正在做的事情,或者简单地(粗暴地)立即杀死线程。在 Perl 中,两者都是通过Thread Signaling实现的。
在第一种情况下(即,如果我们想告诉线程完成它们的工作,然后停止处理共享队列),我们应该使用$thread->kill('KILL')->join():
foreach my $thread ( threads->list() ) { # for each thread...
$thread->kill('KILL')->join(); # wait the thread finish its work and kill it...
print "Number of items in the queue: " . $queue->pending() . "\n" if defined $queue->pending();
print "Number of current threads: " . threads->list() . "\n";
}
另一方面,在后一种情况下(即如果我们想立即终止线程),我们应该使用$thread->kill('KILL')->kill():
foreach my $thread ( threads->list() ) { # for each thread...
$thread->kill('KILL')->kill(); # kill the thread immediately...
print "Number of items in the queue: " . $queue->pending() . "\n" if defined $queue->pending();
print "Number of current threads: " . threads->list() . "\n";
}
当然,如果你想从内部杀死线程,你只需要调用threads->exit()或者简单地使用return:
sub do {
...
threads->exit(); # kill the thread...
...
}