Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I instantly kill a Perl thread without killing the entire program?

When I use exit or die, it kills the entire program.

foreach my $t (threads->list())
{
    $t->exit;
    $count++;
}

Usage: threads->exit(status) at main.pl line 265
Perl exited with active threads:
        9 running and unjoined
        0 finished and unjoined
        0 running and detached

Any ideas?

like image 533
Saustin Avatar asked Aug 09 '11 19:08

Saustin


Video Answer


1 Answers

To ignore a thread that is being executed, return back control and throw away whatever it may output, the right method to use is detach, not exit.

See perldoc perlthrtut - Ignoring a Thread.


perldoc threads explains why the code exits:

threads->exit()

If needed, a thread can be exited at any time by calling threads->exit(). This will cause the thread to return undef in a scalar context, or the empty list in a list context. When called from the main thread, this behaves the same as exit(0).


There may be a way to achieve instant termination (didn't work for me on Windows):

use threads 'exit' => 'threads_only';

This globally overrides the default behavior of calling exit() inside a thread, and effectively causes such calls to behave the same as threads->exit() . In other words, with this setting, calling exit() causes only the thread to terminate. Because of its global effect, this setting should not be used inside modules or the like. The main thread is unaffected by this setting.

The documentation also suggests another way, using the set_thread_exit_only method (Again, didn't work for me on Windows):

$thr->set_thread_exit_only(boolean)

This can be used to change the exit thread only behavior for a thread after it has been created. With a true argument, exit() will cause only the thread to exit. With a false argument, exit() will terminate the application. The main thread is unaffected by this call.


The example below makes use of a kill signal to terminate the $unwanted thread:

use strict;
use warnings;
use threads;

my $unwanted = threads->create( sub {
                                      local $SIG{KILL} = sub { threads->exit };
                                      sleep 5;
                                      print "Don't print me!\n";
                                    } );

my $valid    = threads->create( sub {
                                      sleep 2;
                                      print "This will print!\n";
                                    } );

$unwanted->kill('KILL')->detach;   # Kills $thr, cleans up

$valid->join;                 # sleep 2, 'This will print!'
like image 151
Zaid Avatar answered Sep 28 '22 08:09

Zaid