Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

END block not excuting when thread interrupted

by iankorf (Acolyte)
on Jul 09, 2006 at 02:50 UTC ( [id://559974]=perlquestion: print w/replies, xml ) Need Help??

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

My program defines an END block to clean up after the program ends or if the program is interrupted. The END block is not executed when workers are interrupted with ^C. This is Perl 5.8.6 on Mac/Linux. Here's a simplified code snippet with the same behavior.
#!/usr/bin/perl
use strict; use warnings;
use threads;
use Thread::Queue;

my $Q = new Thread::Queue;
for (my $i = 0; $i < 10; $i++) {$Q->enqueue(int rand 6)}
my @worker;
for (my $i = 0; $i < 4; $i++) {$worker[$i] = threads->create(\&worker, $Q)}
for (my $i = 0; $i < 4; $i++) {$worker[$i]->join}
print STDERR "workers done\n";

sub worker {
	my ($q) = @_;
	my $tid = threads->tid;
	while ($q->pending) {
		my $job = $q->dequeue;
		print STDERR "processing sleep($job) in thread $tid\n";
		sleep($job);
	}
}

END {
	print STDERR "END block executed\n";
}
  • Comment on END block not excuting when thread interrupted

Replies are listed 'Best First'.
Re: END block not excuting when thread interrupted
by starbolin (Hermit) on Jul 09, 2006 at 06:28 UTC

    Woa... Way not enough information. What OS is the code running on? I assume we're talkin itheads? Are you using join() or detach()? Are the worker threads doing system calls? Writing to disk? What do you mean by interupted?

    In general the worker threads have to finish, ie. exit normally, before join() and detach() can clean up.

    From perlthrtut

    "Similarly, mixing signals and threads should not be attempted."


    s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}
Re: END block not excuting when thread interrupted
by HuckinFappy (Pilgrim) on Jul 09, 2006 at 03:05 UTC
    I don't have any helpful advice for threaded programming, but would you have any better luck using a pre-existing solution, and using File::Temp for your temp directory?
    use File::Temp qw/ tempfile tempdir /; $dir = tempdir( CLEANUP => 1 );
Re: END block not excuting when thread interrupted
by jdhedden (Deacon) on Jul 09, 2006 at 17:31 UTC
    First of all, try the latest version of threads. It handles thread exits in a more robust manner.

    Also, please post some sample code so we can see just want you're doing.


    Remember: There's always one more bug.
      Here's a simple code snippet that replicates the behavior. The program creates a job queue with 10 jobs and has 4 workers act on those. The jobs are sleeps from 0-5 sec. If you let the program run to completion, it prints "workers done" and then "END block executed". If you interrupt it with ^C you get nothing, not even an error message.
      #!/usr/bin/perl
      use strict; use warnings;
      use threads;
      use Thread::Queue;
      
      my $Q = new Thread::Queue;
      for (my $i = 0; $i < 10; $i++) {$Q->enqueue(int rand 6)}
      my @worker;
      for (my $i = 0; $i < 4; $i++) {$worker[$i] = threads->create(\&worker, $Q)}
      for (my $i = 0; $i < 4; $i++) {$worker[$i]->join}
      print STDERR "workers done\n";
      
      sub worker {
      	my ($q) = @_;
      	my $tid = threads->tid;
      	while ($q->pending) {
      		my $job = $q->dequeue;
      		print STDERR "processing sleep($job) in thread $tid\n";
      		sleep($job);
      	}
      }
      
      END {
      	print STDERR "END block executed\n";
      }
      

        Try this.

        #!/usr/bin/perl use strict; use warnings; use threads; use Thread::Queue; $SIG{ INT } = sub{ print "Interupted\n"; exit; }; my $Q = new Thread::Queue; for (my $i = 0; $i < 10; $i++) {$Q->enqueue(int rand 6)} my @worker; for (my $i = 0; $i < 4; $i++) {$worker[$i] = threads->create(\&worker, + $Q)} for (my $i = 0; $i < 4; $i++) {$worker[$i]->join} print STDERR "workers done\n"; sub worker { my ($q) = @_; my $tid = threads->tid; while ($q->pending) { my $job = $q->dequeue; print STDERR "processing sleep($job) in thread $tid\n"; sleep($job); } } END { print STDERR "END block executed\n"; } __END__ c:\test>560021.pl processing sleep(0) in thread 1 processing sleep(4) in thread 1 processing sleep(1) in thread 2 processing sleep(0) in thread 3 processing sleep(1) in thread 3 processing sleep(4) in thread 4 processing sleep(3) in thread 2 processing sleep(5) in thread 3 processing sleep(3) in thread 1 processing sleep(2) in thread 2 Interupted END block executed

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: END block not excuting when thread interrupted
by jrockway (Acolyte) on Jul 09, 2006 at 23:33 UTC
    Why not add a signal handler for $SIG{INT} to the parent? For example, if I add this:
    sub sigint { die "Dying."; } $SIG{INT} = \&sigint;
    to your program up at the top, everything exits fine on SIGINT, and the end block is executed:
    $ perl test.pl processing sleep(0) in thread 1 processing sleep(1) in thread 1 processing sleep(3) in thread 3 processing sleep(0) in thread 4 processing sleep(2) in thread 4 processing sleep(4) in thread 2 processing sleep(0) in thread 1 processing sleep(3) in thread 1 processing sleep(4) in thread 4 processing sleep(5) in thread 3 <C-c> Dying. at test.pl line 25. END block executed A thread exited while 3 threads were running.
    You probably want to do something other than die(), but same idea. SIGCHLD (ignored by default) will catch child deaths, if that's what you wanted originally.
      Many thanks jrockway and BrowserUk.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://559974]
Approved by McDarren
Front-paged by bart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (2)
As of 2024-04-16 23:47 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found