raz3r
raz3r

Reputation: 3131

How to cleanup threads once they have finished in Perl?

I have a Perl script that launches threads while a certain expression is verified.

while ($launcher == 1) {
    # do something
    push @threads, threads ->create(\&proxy, $parameters);
    push @threads, threads ->create(\&ping, $parameters);
    push @threads, threads ->create(\&dns, $parameters);
    # more threads
    foreach (@threads) {
    $_->join();
    }
}

The first cycle runs fine but at the second one the script exits with the following error:

Thread already joined at launcher.pl line 290. Perl exited with active threads: 1 running and unjoined 0 finished and unjoined 0 running and detached

I guess I shall clean @threads but how can I do that? I am not even sure if this is the problem.

Upvotes: 2

Views: 2774

Answers (2)

choroba
choroba

Reputation: 241758

Just clear @threads at the end of the loop:

@threads = ();

Or better, declare @threads with my at the beginning of the loop:

while ($launcher == 1) {
    my @threads;

Upvotes: 5

flesk
flesk

Reputation: 7579

The easiest solution would be to create the array inside the while loop (while {my @threads; ...}), unless you need it anywhere else. Otherwise you could just @threads = () or @threads = undef at the end of the while loop.

You could also set a variable my $next_thread; outside the while loop and then assign $next_thread = @threads first thing in the while loop and change your foreach loop to

for my $index ($next_thread .. $#threads) {
    $threads[$index]->join();
}

or skip that and just loop over a slice of the last three added threads

for (@threads[-3..-1) {
    $_->join();
}

Upvotes: 2

Related Questions