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 に答える