Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 系统命令中的线程超时_Multithreading_Perl_Interrupt Handling - Fatal编程技术网

Multithreading 系统命令中的线程超时

Multithreading 系统命令中的线程超时,multithreading,perl,interrupt-handling,Multithreading,Perl,Interrupt Handling,我有一个看似简单的问题。我需要执行一系列的 并行执行系统命令(使用反引号) 下面的代码已经删除了除此之外的任何有意义的内容 演示我的问题: #!/usr/bin/perl -w use strict; use threads; use POSIX; my @threads = (); sub timeout { print "TIMEOUT\n"; foreach my $thread (@threads) { $thread->kill("ALRM") i

我有一个看似简单的问题。我需要执行一系列的 并行执行系统命令(使用反引号)

下面的代码已经删除了除此之外的任何有意义的内容 演示我的问题:

#!/usr/bin/perl -w 
use strict; 
use threads; 
use POSIX; 
my @threads = (); 
sub timeout { 
  print "TIMEOUT\n"; 
  foreach my $thread (@threads) { 
    $thread->kill("ALRM") if $thread->is_running(); 
  } 
} 

POSIX::sigaction(SIGALRM, POSIX::SigAction->new(\&timeout)); 
alarm(2); 
sub threadsub { 
  sub handletimeout { 
    print "KILL\n"; 
    threads->exit(1); 
  } 
  POSIX::sigaction(SIGALRM, POSIX::SigAction->new(\&handletimeout)); 
  # while(1) { sleep(1); } 
  return `sleep 10`; 
} 

for(my $i=0; $i < 10; $i++) { 
  push(@threads, thread->create(\&threadsub)); 
} 

foreach my $thread (@threads) { 
  my $res = $thread->join(); 
}
#/usr/bin/perl-w
严格使用;
使用线程;
使用POSIX;
我的@threads=();
子超时{
打印“超时\n”;
foreach my$thread(@threads){
$thread->kill(“ALRM”)如果$thread->正在运行();
} 
} 
POSIX::sigaction(SIGALRM,POSIX::sigaction->new(\&timeout));
警报(2);
子线程sub{
子句柄输出{
打印“KILL\n”;
线程->退出(1);
} 
POSIX::sigaction(SIGALRM,POSIX::sigaction->new(\&handletimeout));
#while(1){sleep(1);}
返回'sleep 10';
} 
对于(my$i=0;$i<10;$i++){
推送(@threads,thread->create(\&threadsub));
} 
foreach my$thread(@threads){
my$res=$thread->join();
}
现在,问题是发送到线程的ALRM信号永远不会被删除 在系统调用中阻止线程时捕获。如果你取消注释 当信号被捕捉到时,环路按预期进行。 我如何使这项工作,使我能够超时我的线程,即使 他们被系统命令卡住了

谢谢


Kasper

来自人工线程

   Unsafe signals
       Since Perl 5.8.0, signals have been made safer in Perl by postponing their handling until the interpreter is in a safe state.  See "Safe
       Signals" in perl58delta and "Deferred Signals (Safe Signals)" in perlipc for more details.

       Safe signals is the default behavior, and the old, immediate, unsafe signalling behavior is only in effect in the following situations:

       ?   Perl has been built with "PERL_OLD_SIGNALS" (see "perl -V").

       ?   The environment variable "PERL_SIGNALS" is set to "unsafe" (see "PERL_SIGNALS" in perlrun).

       ?   The module Perl::Unsafe::Signals is used.

       If unsafe signals is in effect, then signal handling is not thread-safe, and the "->kill()" signalling method cannot be used.
这实际上表明,信号将延迟到perl处于不安全状态。如果我们切换到“不安全信号”,程序将终止,并显示消息在threads.pl处不能向没有安全信号的线程发送信号。请检查不安全信号是否在您的系统中工作。虽然它可以工作,但它是不安全的。建议迁移到进程。下面的代码将为您提供所需的结果

use strict;
use POSIX;

my $pid=fork();

sub timeout {
  print "TIMEOUT\n";
  kill SIGALRM,$pid;
}

if( $pid ) { ## parent
    alarm(2);
    POSIX::sigaction(SIGALRM, POSIX::SigAction->new(\&timeout));
    waitpid $pid,0;
} else { ## child
    sub handletimeout {
        print "SIGALRM child\n";
        exit(1);
    }
    POSIX::sigaction(SIGALRM, POSIX::SigAction->new(\&handletimeout));
    `sleep 10`;
    print "child normal exit";
}

作为解决方法,我现在已经成功地使用了threads::shared中的条件变量。然后,我可以将中断处理保留在主线程中,并让这个块继续等待,而不是$thread->join()。在超时时,我使用detach从主线程终止线程。我仍然希望上面的代码能够很好地工作。