1

我有一个使用线程的 Perl 脚本,如何在函数成功执行后退出函数而不退出脚本?

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

我的原始脚本是单片的,没有任何功能,完成后它只是“退出”;

这就是我创建线程的方式:

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

和我的潜艇:

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

编辑

我的完整脚本有问题:

#!/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";
4

2 回答 2

4

如果您希望在退出之前完成所有线程,则需要在某个时候加入它们。

您可以在脚本结束之前添加类似这样的内容:

for my $thread (threads->list)                                                                                   
{                                                                                                                
      $thread->join();                                                                               
}   
于 2013-02-27T09:32:35.397 回答
1

更新: Tim De Lange 加入线程的解决方案可能是您想要的。但在某些情况下,以下方法可能有用。

您可以实现一些等待逻辑,以确保在退出之前一切都已完成。这是一个简单的例子:

#!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();

解释:

  1. 获取正在运行的线程数的计数。
  2. 启动任何涉及线程的任务。
  3. 在退出程序之前,等到线程数等于原始数(您启动的所有线程都已停止)。
于 2013-02-27T09:30:38.280 回答