http://www.perlmonks.org?node_id=1020728

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

Hello,

I found node 704138 with the same question for an almost similar situation, but alas, there were no usable solutions for me.

I'm working on a Perl script to shutdown AIX lpars from an AIX server (6.1) via the local HMC. As there are a lot of lpars and limited time, I've decided to use threads to split the load, with each thread a number of lpars to stop.

Now it's a big possibility that some threads will not end in time, which I want to kill after a time-out. However, the 5.8.8 version doesn't support threads->exit(). How dot I get rid of the thread?

Code snippets

use threads; our @lparList = (); my @jobs = (); my $timeOut=1; # ... fill lparList from file, 1 array element per line. # (Line can consist of 1 or more , separated lparsnames sub manageLPAR ($$) { my $action = shift; my @LPARs=split (',',$_[0]); my $die = 0; print("Thread ",threads->self->tid(), " Started.\n"); $SIG{ALRM} = sub { print("Thread ",threads->self->tid(), " got SIGALRM.\n"); $action =~ s/^S/s/; print("Timeout in $action"); if ( $action eq "stop" ) { print("p"); } print("ing @LPARs. Good bye.\n"); $die = 1; #return; threads->exit(); #die "Got SIGALRM in stopLPAR Good bye.\n"; }; ... do stuff print("Thread ",threads->self->tid(), " Finished normally.\n"); } # main foreach $lpar ( @lparList ) { push @jobs, threads->create( sub { threads->yield(); manageLPAR ($action,$lpar); }); } # Wait $timeOut seconds for thread to finish. # kill thread when time is passed. $SIG{ALRM} = sub { foreach my $job (@jobs) { if ($job->is_running) { $job->kill('ALRM'); } } }; alarm($timeOut); # Wait for all jobs to finish or timeout $_->join for @jobs; # Wait for everything to finish.

The snippet was based on another script I made for another site, with a newer Perl.

At this moment I have the 'return' option implemented with the die variable, but this doesn't work, but at least doesn't give an error. (and scares the coworkers) Whatever option I use, die, return or threads->exit(), the result is the same, no exit what so ever. (except for the error caused by threads->exit which doesn't exist)

The problem I have now is the loop which sends the ALRM signal. It just reaches 1 thread and hangs. (because it waits for the thread to exit, which it doesn't) I have to kill the thread, not knowing or even caring what it does, it just has to go.

The only solution I see at the moment is to skip threads and run external commands, wait for the timeout and kill the children. I'm stuck with this Perl version and would like to solve this in Perl, with the use of threads.

Thanks for any advice you have.

Edit: Tested with another Perl 5.8.8 version for AIX 6.1 (/opt/freeware version) and there I don't get the error, but the same result. The 'for' loop to send the signals halts after sending the signal to the first thread. I've tested with a newer perl (5.10.1) for AIX 6.1 and get the same result there. See below for output. Both threads have been configured with enough work for at least 10 seconds. (and timeout is set to 1)

Thread 1 Started. Thread 2 Started. Thread 1 got SIGALRM. Timeout in stopping <@LPARs>. Good bye. Thread 2 Finished normally.