在这个程序中,我创建一个fork,然后从中调用domultithreading。然后它创建一些线程。
sub domultithreading {
#Not my function
my ($num) = @_;
my @thrs;
my $i = 0;
my $connectionsperthread = 50;
while ( $i < $num ) {
$thrs[$i] = threads->create( \&doconnections, $connectionsperthread, 1 );
$i += $connectionsperthread;
}
my @threadslist = threads->list();
while ( $#threadslist > 0 ) {
$failed = 0;
}
}
sub kill {
#how can I kill the threads made in domultithreading?
kill 9, $pid;
print "\nkilling $pid\n";
}
然后我希望能够杀死fork及其线程,但是我无法弄明白。有什么建议吗?
非常感谢
答案 0 :(得分:5)
Perl提供了两种并发模型:进程和线程。虽然你不应该在没有充分理由的情况下将这两者混合在一起,但是线程会非常密切地建模过程,因此我们几乎可以对它们进行处理。具体来说,我们可以向线程发送信号。
可以使用kill
函数:kill SIGNAL => $pid
发出进程信号,而线程可以使用kill
方法发出信号: $thr->kill(SIGNAL)
。此方法返回线程对象。在%SIG
哈希值中设置信号处理程序时,可以拦截信号。
这意味着每个进程TERM
信号处理程序TERM
都是所有子线程,如
$_->kill(9)->join() for threads->list;
并且每个线程TERM
信号处理程序只是退出线程,或者进行清理:
threads->exit; # exit the current thread
答案 1 :(得分:1)
实际上很少有不同的方法可以杀死Perl中的thread,具体取决于你想要实现的目标。
我们以下面的代码为例:
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-&gt; end()),所以线程将被连接(到主)一次他们已经处理了队列的所有元素。实际上,使用 $ thread-&gt; join(),我们要求主要等待 $ thread 加入。
如果我们省略声明 $ queue-&gt; end(),则线程将不会加入main,但会保留队列中新元素的待处理状态。
现在,如果我们想杀死线程,我们有两个选择:杀死线程但让他们先完成他们正在做的事情,或者简单地(粗暴地)立即杀死线程。在Perl中,两者都是通过Thread Signalling实现的。
在第一种情况下(即如果我们想告诉线程完成他们的工作,之后,停止处理共享队列),我们应该使用 $ thread-&gt; kill('KILL') - &gt; 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-&gt; kill('KILL') - &gt; 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-&gt; exit()或者只需使用 return :
sub do {
...
threads->exit(); # kill the thread...
...
}