我的代码如下:
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
如何解决这个问题?
答案 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();