http://qs321.pair.com?node_id=997094

DanEllison has asked for the wisdom of the Perl Monks concerning the following question:

I have a multithreaded application which spawns threads to track work. The single parent thread creates all the children threads. Each child thread executes an external command and then captures the output via an open on a pipe. If the child thread doesn't complete within some time limit, the parent sends the child a signal, and the child in turn attempts to kill the external process.

I'm not sure if its the fact that its windows and emulated, or if its due to some rule regarding waiting on I/O, but the child thread doesn't appear to be acting immediately on the signals. When I interupt the parent, then the child thread suddenly reports the earlier signals.

I don't want to SIGKILL the child thread as I want it to report what it had accomplished to that point. However, I set it up so that if I sent it a NUM16, it would do a SIGKILL on the external command. Since this didn't have any effect, it appears that its the child thread that is not responding, not the external command.

Maybe there's a totally better way of doing this.... Following is a snippet of the child thread code.

$self->msg('execute', dir => Cwd::getcwd(), cmd => $self->{cmd}, 'eval +' => $cmd); my $pid = open EXEC, "-|", "($cmd)2>&1" or die "Could not start comman +d."; foreach ( qw{ ABRT ALRM BREAK FPE HUP ILL INT PIPE QUIT SEGV STOP TERM + } ) { $SIG{$_} = sub { warn "$self->{-full}: Signal $_ caught"; $self->msg +('signal', signal => $_[0]); kill $_[0], $pid; }; } foreach ( qw{ USR1 NUM16 } ) { $SIG{$_} = sub { warn "$self->{-full}: Signal $_ caught"; $self->msg +('signal', signal => 'KILL'); kill 'KILL', $pid; }; } while (<EXEC>) { chomp; $self->msg('execute', output => $_); } close EXEC; $self->set(status => $?, stop => Scheduler::Time::utc); foreach ( qw{ ABRT ALRM BREAK FPE HUP ILL INT PIPE QUIT SEGV STOP TERM + USR1 NUM16 } ) { $SIG{$_} = 'DEFAULT'; };