Perl线程与闹钟

4

在Perl (>=5.012) 线程中,有没有办法实现闹钟(或其他超时机制)?

1个回答

6
在主线程中运行alarm,使用信号处理程序来向活动线程发送信号。
use threads;
$t1 = threads->create( \&thread_that_might_hang );
$t2 = threads->create( \&thread_that_might_hang );
$SIG{ALRM} = sub {
    if ($t1->is_running) { $t1->kill('ALRM'); }
    if ($t2->is_running) { $t2->kill('ALRM'); }
};

alarm 60;
# $t1->join; $t2->join;
sleep 1 until $t1->is_joinable; $t1->join;
sleep 1 until $t2->is_joinable; $t2->join;
...

sub thread_that_might_hang {
    $SIG{ALRM} = sub { 
        print threads->self->tid(), " got SIGALRM. Good bye.\n";
        threads->exit(1);
    };
    ... do something that might hang ...
}

如果您需要为每个线程设置不同的警报,请看一下可以设置多个警报的模块,例如Alarm::Concurrent

编辑:评论者指出threads::join会干扰SIGALRM,因此您可能需要测试$thr->is_joinable而不是调用$thr->join


3
当我尝试这个解决方案时,它在我的系统上卡住了,alarm 从未触发。看起来 join 阻塞了 SIGALRM。这是过去五年中的新行为吗? - CDahn
1
@CDahn我遇到了同样的问题。本来在寻找非阻塞的thr->join(),但是没有,所以现在我打算用thr->is_joinable()来轮询线程状态,以免阻塞SIGALRM。 - solstice333

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接