【问题标题】:Perl threads with alarm带有警报的 Perl 线程
【发布时间】:2011-09-14 01:02:01
【问题描述】:

有没有办法在 perl (>=5.012) 线程中获得警报(或其他一些超时机制)?

【问题讨论】:

    标签: multithreading perl timeout


    【解决方案1】:

    在您的主线程中运行 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

    【讨论】:

    • 当我尝试这个解决方案时,它会挂在我的系统上,alarm 永远不会关闭。 join 似乎阻止了 SIGALRM。这是过去 5 年的新行为吗?
    • @CDahn 我遇到了同样的问题。正在寻找一个非阻塞的thr->join(),但没有,所以现在我正在考虑用thr->is_joinable() 轮询线程状态,所以我不阻塞SIGALRM
    猜你喜欢
    • 1970-01-01
    • 2015-10-05
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多