1

私のプログラムは次のようなものです。

use strict;
use threads;
use threads::shared;

my @thr;
for (my $i = 0; $i < $ARGV[0]; $i++) {
    $thr[$i] = threads->create(\&Iteration, $i);
}

foreach (@thr) {
    if ($_->is_running()) {
        print "no";
    }
    else{
        $_->join;
    }
}

sub Iteration {
    my $in = shift;
    print "test$in\n";
}

しかし、$ ARGV [0]、たとえば5で実行すると、出力は次のようになります。

test2
test1
test0
test3
test4
Can't locate auto/threads/is_running.al in @INC 

では、is_running()ステートメントを使用してスレッドの1つのステータスを確認するにはどうすればよいですか?

4

2 に答える 2

1

正しく見えます。そのメッセージは、サブが存在しないことを示しているので、そのようなメソッドがない古いバージョンのスレッドを使用していると思われます。その場合は、スレッドモジュールをアップグレードしてください。

cpan threads

以下に、インストールしたバージョンを示します(現在は1.86、1.34にis_running追加されたようです)。

perl -Mthreads -le'print $threads::VERSION'

以下に、インストールしたバージョンのドキュメントを提供します。

perldoc threads
于 2012-09-24T17:59:46.620 に答える
1

本当にアップグレードできない場合はis_running、スレッドIDの共有テーブルを使用して自分で簿記のように実装できます。何かのようなもの:

package Untested::Workaround;
#
# my $thr = Untested::Workaround->spawn(\&routine, @args);
# ...
# if (Untested::Workaround->is_running($thr)) ...
#
#
...
our %Running : shared;        # Keys are "running" tids

sub _bookkeeping {
  my ($start_routine, @user_args) = @_;
  my $ret;

  { lock(%Running); $Running{ threads->tid() } = 1; }
  $ret = $code->(@args);
  { lock(%Running); delete $Running{ threads->tid() }; }

  $ret;
}

sub spawn {
  shift; #ignore class
  threads->create(\&_bookkeeping, @_);
}

sub is_running { lock %Running; $Running{ $_[1]->tid() }; }

繰り返しますが、上記はテストされていません。名前空間をサブクラス化threadsまたは変更threadsして、より現代的でより自然なAPIを提供するように改善することができます。threads(また、開始ルーチンのために保持される呼び出し元コンテキストも無視します。)

于 2012-09-24T18:38:35.103 に答える