How can I kill Perl threads?

In this program, I create a fork and then call domultithreading from it. Then it creates several threads.

sub domultithreading { #Not my function my ($num) = @_; my @thrs; my $i = 0; my $connectionsperthread = 50; while ( $i < $num ) { $thrs[$i] = threads->create( \&doconnections, $connectionsperthread, 1 ); $i += $connectionsperthread; } my @threadslist = threads->list(); while ( $#threadslist > 0 ) { $failed = 0; } } sub kill { #how can I kill the threads made in domultithreading? kill 9, $pid; print "\nkilling $pid\n"; } 

Then I want to kill the plug and its flows, but I can not understand it. Any suggestions?

thanks a lot

+2
source share
2 answers

Perl provides two concurrency models: Processes and Threads. Although you do not have to mix these two for no good reason, threads pretty much simulate processes, so we can treat them as such. In particular, we can send signals to streams.

Processes can be signaled with the kill : kill SIGNAL => $pid function, while threads can be signaled with the kill : $thr->kill(SIGNAL) method. This method returns a stream object. Signals can be intercepted when installing signal handlers in the %SIG hash.

This means that every TERM process handler TERM all child threads, such as

  $_->kill(9)->join() for threads->list; 

and each TERM thread the signal handler simply exits the thread or does a cleanup:

  threads->exit; # exit the current thread 
+5
source

In Perl, there are several different ways to kill thread , depending on what you want to achieve.

Take the following code as an example:

 use strict; use warnings; use threads; use Thread::Queue; # Create the shared queue (used by the threads): my $queue = Thread::Queue->new(); sub main { # Initialise the shared queue: $queue->enqueue("A", "B", "C", "D", "E", "F"); print "Total number of items: " . $queue->pending() . "\n"; $queue->end(); # signal that there is no more work to be sent... # Create 3 threads: threads->create('do') for ( 0..2 ); print "Number of current threads: " . threads->list() . "\n"; foreach my $thread ( threads->list() ) { # for each thread... $thread->join(); # wait the thread to finish all its work... print "Number of items in the queue: " . $queue->pending() . "\n" if defined $queue->pending(); print "Number of current threads: " . threads->list() . "\n"; } } sub do { # Retrieve the current thread ID: my $threadID = threads->self()->tid(); # Setup the thread kill signal handler: local $SIG{KILL} = sub { threads->exit() }; while ( defined (my $item = $queue->dequeue()) ) { # for each element in the queue... print "(Thread-" . $threadID . "): Do something with item '$item'...\n"; sleep 1 + $threadID; print "(Thread-" . $threadID . "): Finished to use item '$item'...\n"; } } main(); 

In the above code, 3 threads are created, each of which will receive and process the element of the general queue until the queue is empty.

In this case, since we announced that no more elements will be added to the queue (for example, $ queue-> end ()), the threads will be connected (to the main one) after they have processed all the elements in the queue. In fact, using $ thread-> join (), we tell the main thing to wait for $ thread to join.

If we omit declaring $ queue-> end (), the threads will not join the main one, but will remain pending for new queue elements.

Now, if we want to kill streams, we have two options: kill streams, but letting them finish what they do first or simply (brutally) by killing streams immediately. In Perl, both are achieved using Thread Signaling .

In the first case (that is, if we want the threads to finish working, and then to stop processing the shared queue), we should use $ thread-> kill ('KILL') → join ():

 foreach my $thread ( threads->list() ) { # for each thread... $thread->kill('KILL')->join(); # wait the thread finish its work and kill it... print "Number of items in the queue: " . $queue->pending() . "\n" if defined $queue->pending(); print "Number of current threads: " . threads->list() . "\n"; } 

On the other hand, in the latter case (i.e. if we want to kill the threads immediately), we must use $ thread-> kill ('KILL') → kill ():

 foreach my $thread ( threads->list() ) { # for each thread... $thread->kill('KILL')->kill(); # kill the thread immediately... print "Number of items in the queue: " . $queue->pending() . "\n" if defined $queue->pending(); print "Number of current threads: " . threads->list() . "\n"; } 

Of course, if you want to kill the thread from the inside, you just need to call threads-> exit () or just use return :

 sub do { ... threads->exit(); # kill the thread... ... } 
+1
source

All Articles