2012-11-20 38 views
1

我正在尝试处理线程中的超时。我的脚本有4个线程,每个线程都需要执行命令,如果命令过程耗时过长,就会终止命令。如何在线程内正确地退出子进程?

什么我做的是:

my $pid; 
if (!($pid = fork)) 
    {                                                 
    my $pid2; 
    if (!($pid2 = fork)) 
     { 
     exec_cmd $command; 
     } 
    local $SIG{ALRM} = sub {kill 9, $pid2;}; 
    alarm $timeout; 
    waitpid $pid2, 0; 

    exit(0); 
    } 
    waitpid $pid, 0; 
    $ret = $?; 

这是一个线程中执行,因此当孩子退出,其他线程仍然未连接。

+1

此代码使用分叉,而不是线程。 –

+0

是的,但它只是脚本的一部分,这段代码在一个线程内调用 – Robin

+0

你的问题是什么? – pilcrow

回答

2

认为你问,我该如何强制执行从perl线程产生的子进程的执行时间,并捕获该子进程的退出代码?

你可以做(在UNIX系统上)最简单的事情是设置一个报警的子过程本身:

my $pid = fork(); 
if (defined($pid) and $pid == 0) { 
    alarm($timeout); # Preserved across exec() 
    exec(...); 
    die "exec(): $!"; 
} 

退出状态仍然会提供waitpid/$?如常。

你可以做的最安全的事情是不是在多线程时分叉。这对应用程序和实现都是危险的。该应用程序,因为该孩子将运行父母的线程的副本。这个实现,因为这样做比较容易从threads强制“非平衡范围/节省/ tmps /上下文”错误。

+0

如何超时一个线程内的命令,而不分叉呢? 如果警报在exec中保留,它应该可以工作,但如果它不安全,可能需要另一种解决方案。什么可以工作? – Robin