Multithreading 如何正确退出线程中的子进程?

Multithreading 如何正确退出线程中的子进程?,multithreading,perl,fork,Multithreading,Perl,Fork,我试图处理线程内的超时。我的脚本有4个线程,每个线程都需要执行命令,如果需要的时间太长,就终止命令进程 我正在做的是: my $pid; if (!($pid = fork)) {

我试图处理线程内的超时。我的脚本有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 = $?;
这是在一个线程内执行的,因此当子线程退出时,其他线程仍然没有连接。

我想您是在问,我如何对从perl线程派生的子进程的执行实施时间限制,并捕获该子线程的退出代码

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

my $pid = fork();
if (defined($pid) and $pid == 0) {
  alarm($timeout);  # Preserved across exec()
  exec(...);
  die "exec(): $!";
}
退出状态仍将像往常一样在
waitpid
/
$?
中可用


您可以做的最安全的事情是在多线程时不要使用fork。这对应用程序和实现都是危险的。应用程序,因为子线程将具有父线程的运行副本。实现,因为这样做时很容易从
线程强制“不平衡的作用域/保存/tmps/context”错误。

此代码使用fork,而不是线程。是的,但它只是脚本的一部分,这段代码在线程内调用。当其他线程仍在运行时,如何正确退出线程内的子进程。exec_cmd函数调用exec,因此没有问题。然而,第一个fork需要使用cmd的exit状态退出,如果我只是退出Perl,它会说仍然有正在运行的线程,这是正常的,但是如何退出这些线程呢?我已经尝试通过遍历threads->list()和kill('kill')->detach来杀死它们,但后来它仍然显示一条消息,说有分离的threads线程和forks不能很好地协同工作。我不知道perl是如何实现线程的,但很有可能在一个fork之后,子进程以父进程在fork时拥有的所有线程结束,因此您看到的延迟线程是由fork创建的额外线程。如何在没有fork的情况下使线程内的命令超时?若警报在整个exec中被保留,它应该可以工作,但若它不安全,也许我需要另一个解决方案。什么能起作用?