Perl如何加入所有线程

时间:2015-07-06 20:47:23

标签: perl

我的代码如下:

use threads;
use threads::shared;
use Thread::Queue;

my $q = Thread::Queue->new();
my @threads = ();
my $run :shared = 1;

$SIG{'TERM'} = sub {
    $run = 0;
    $q->enqueue('exit');
    foreach(@threads){
        $_->join();
    }
};

push @threads, threads->create(proc1);
push @threads, threads->create(proc2);

sub proc1 {

    while($p = $q->dequeue()){
        if($p eq 'exit'){
            last;
        }
        .....
    }
    $q->end();
    threads->exit();
}

sub proc2 {
    while($run){
       .....
    }
}

在TERM信号我试图等待所有线程结束。但是,每当我通过TERM信号时,我的程序都会因错误而终止

Segmentation fault

如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

假设refreshData甚至可以正常工作(这只是因为你没有使用threads->create(proc1)),那么你的程序会在创建线程后立即退出。您需要让主线程等待子线程完成。

修复该问题(并应用一些简化)会产生以下结果:

use strict;

我没有遇到段错,但程序也没有退出。简单地不调用信号处理程序。这是因为Perl在调用信号处理程序之前等待use strict; use warnings; use threads; use threads::shared; use Thread::Queue 3.01 qw( ); my $q = Thread::Queue->new(); my $run :shared = 1; $SIG{TERM} = sub { print("Received SIGTERM. Shutting down...\n"); $run = 0; $q->end(); }; print("$$\n"); threads->create(\&proc1); threads->create(\&proc2); $_->join() for threads->list(); sub proc1 { while(my $p = $q->dequeue()) { sleep 1; # Placeholder } } sub proc2 { while($run){ sleep 1; # Placeholder } } 返回。您可以通过轮询可连接线程列表来解决这个问题。换句话说,替换

join

$_->join() for threads->list();