Perl how to join all threads

My code is as follows:

use threads;
use threads::shared;
use Thread::Queue;

my $q = Thread::Queue->new();
my @threads = ();
my $run :shared = 1;

$SIG{'TERM'} = sub {
    $run = 0;
    $q->enqueue('exit');
    foreach(@threads){
        $_->join();
    }
};

push @threads, threads->create(proc1);
push @threads, threads->create(proc2);

sub proc1 {

    while($p = $q->dequeue()){
        if($p eq 'exit'){
            last;
        }
        .....
    }
    $q->end();
    threads->exit();
}

sub proc2 {
    while($run){
       .....
    }
}

TERM signal trying to wait for all threads to finish. However, whenever I send a TERM signal, my program fails

Segmentation fault

How to fix it?

+4
source share
1 answer

Assuming that threads->create(proc1)it even works (and that would only be because you didn’t use use strict;it as you should), your program will exit immediately after creating the threads. You need your main thread to wait for the children to finish streams.

Fixing this problem (and applying some simplifications) leads to the following:

use strict;
use warnings;
use threads;
use threads::shared;
use Thread::Queue 3.01 qw( );

my $q = Thread::Queue->new();
my $run :shared = 1;

$SIG{TERM} = sub {
    print("Received SIGTERM. Shutting down...\n");
    $run = 0;
    $q->end();
};

print("$$\n");

threads->create(\&proc1);
threads->create(\&proc2);

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

sub proc1 {
    while(my $p = $q->dequeue()) {
        sleep 1;  # Placeholder
    }
}

sub proc2 {
    while($run){
        sleep 1;  # Placeholder
    }
}

seg, . . , Perl join . , . ,

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

my $running_threads = 2;
while ($running_threads) {
    for my $thread (threads->list(threads::joinable)) {
        $thread->join();
        $running_threads--;
    }

    sleep 1;
}
+3

All Articles