3

在这个程序中,我创建了一个 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";
}

然后我希望能够杀死叉子及其线程,但是我无法弄清楚。有什么建议么?

非常感谢

4

2 回答 2

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
于 2012-12-04T18:19:26.170 回答
2

实际上,在 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...
    ...
}
于 2014-12-29T14:41:08.670 回答