我如何杀死Perl线程?

时间:2012-12-04 17:48:24

标签: multithreading perl fork

在这个程序中,我创建一个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及其线程,但是我无法弄明白。有什么建议吗?

非常感谢

2 个答案:

答案 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...
    ...
}
相关问题