English 中文(简体)
处于系统指挥状态时的距离
原标题:Timeout thread while it is in a system command

I have a seemingly simple problem. I need to execute a series of system commands (using backquotes) in parallel.

The code below has been stripped of anything meaningful besides demonstrating my problem:

#!/usr/bin/perl -w 
use strict; 
use threads; 
use POSIX; 
my @threads = (); 
sub timeout { 
  print "TIMEOUT
"; 
  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
"; 
    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(); 
}

Now, the problem is the ALRM signal sent to the threads are never caught when the thread is blocked in the system call. If you uncomment the while loop the signal are caught as intended. How do I make this work so I m able to timeout my threads even if they re stuck in the system command?

感谢

Kasper

最佳回答

http://strong>man threads

   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.

这种内分效应表明,信号将推迟到无安全状态。 如果我们转向不安全的签字方案,用的电文终止。 Cannot sign threads without safety signs.pl. 请检查un-safe sign在您的系统中的工作。 虽然它的工作是un-safe。 建议移徙到进程。 下面的法典应当给你预期的结果。

use strict;
use POSIX;

my $pid=fork();

sub timeout {
  print "TIMEOUT
";
  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
";
        exit(1);
    }
    POSIX::sigaction(SIGALRM, POSIX::SigAction->new(&handletimeout));
    `sleep 10`;
    print "child normal exit";
}
问题回答

暂无回答




相关问题
Why does my chdir to a filehandle not work in Perl?

When I try a "chdir" with a filehandle as argument, "chdir" returns 0 and a pwd returns still the same directory. Should that be so? I tried this, because in the documentation to chdir I found: "...

How do I use GetOptions to get the default argument?

I ve read the doc for GetOptions but I can t seem to find what I need... (maybe I am blind) What I want to do is to parse command line like this myperlscript.pl -mode [sth] [inputfile] I can use ...

Object-Oriented Perl constructor syntax and named parameters

I m a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot. package Foo; #In Perl, the constructor is just a subroutine called new. sub new { #I ...

Where can I find object-oriented Perl tutorials? [closed]

A Google search yields a number of results - but which ones are the best? The Perl site appears to contain two - perlboot and perltoot. I m reading these now, but what else is out there? Note: I ve ...

热门标签