bsteo
bsteo

Reputation: 1779

Exit perl function without exiting script

I have a Perl script working with threads, how can I exit a function without exiting the script after the function is successfully executed?

Perl exited with active threads:
        6 running and unjoined
        1 finished and unjoined
        0 running and detached

My original script was monolithic without any functions and when done it just did "exit;"

This is how I created the threads:

for(0..$threads-1) {$trl[$_] = threads->create(\&mysub, $_);}
for(@trl) { $_->join; }

and my sub:

sub mysub {
# do something and if success
exit;
}

EDIT

My full script with problems:

#!/usr/bin/perl

use LWP::UserAgent;
use HTTP::Cookies;
use threads;
use threads::shared;

################################################## ######
$|=1;
my $myscript = '/alive.php';
my $h = 'http://';
my $good : shared = 0;
my $bad : shared = 0;
$threads = 10;
################################################## ######
open (MYLOG , "<myservers.log");
chomp (my @site : shared = <MYLOG>);
close MYLOG;
################################################## ######
$size_site = scalar @site;
print "Loaded sites: $size_site\n";
################################################## ######
my $browser = LWP::UserAgent->new;
$browser -> timeout (10);
$browser->agent("User-Agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.8;" . $browser->agent);

################################################## ######
for(0..$threads-1) {$trl[$_] = threads->create(\&checkalive, $_);}
for(@trl) { $_->join; }
################################################## ######
sub checkalive {

while (@site){

{lock(@site);$url = shift @site;}
$request = $browser->get("$h$url$myscript")->as_string;
if ($request =~ /Server Alive/){open (GOOD , ">>alive.txt");print GOOD "$h$url$myscript\n"; $good++;} else {$bad++;}
print "Alive: $good Offline: $bad\r";
}
}
close GOOD;
print "Alive: $good Offline: $bad\n";

Upvotes: 1

Views: 1607

Answers (2)

user1919238
user1919238

Reputation:

Update: Tim De Lange's solution of joining the threads is probably what you want. But in certain cases the following approach may be useful.

You could implement some waiting logic to make sure everything is complete before you exit. Here is a simple example:

#!usr/bin/perl
use strict;
use warnings;
use threads;

sub threaded_task {
    threads->create(sub { sleep 5; print("Thread done\n"); threads->detach() });
}

sub main {
    #Get a count of the running threads.
    my $original_running_threads = threads->list(threads::running);

    threaded_task();

    print "Main logic done.  Waiting for threads to complete.\n";

    #block until the number of running threads is the same as when we started.
    sleep 1 while (threads->list(threads::running) > $original_running_threads);

    print "Finished waiting for threads.\n";
}

main();

Explanation:

  1. Get a count of the number of running threads.
  2. Start any tasks involving threads.
  3. Before exiting the program, wait until the count of threads equals the original count (all the threads you started have stopped).

Upvotes: 1

Tim De Lange
Tim De Lange

Reputation: 739

If you want all your threads to complete before you exit, you need to join them at some point.

You can add something like this before the end of the script:

for my $thread (threads->list)                                                                                   
{                                                                                                                
      $thread->join();                                                                               
}   

Upvotes: 4

Related Questions