1

私は、Perl の Thread::Queue を使用して、ボス ワーカー クルーのマルチスレッド シナリオで作業しています。
ボスはタスクをキューに入れ、ワーカーはキューからデキューします。
上司が x 秒間キューを介してタスクを送信しない場合に備えて、ワーカー クルーがダウンストリーム ping メッセージを送信するようにする必要があります。
残念ながら、タイムアウトのある dequeue メソッドはないようです。
私は何かを見逃しましたか、それとも別のアプローチ/別のデータ構造をお勧めしますか?

4

2 に答える 2

1

オブジェクトが共有配列への祝福された参照であることを知って、自分で機能を追加することができますThread::Queue(これは、5.8から5.16までの実装であると私は信じています)。

package Thread::Queue::TimedDequeue;

use parent 'Thread::Queue';
use threads::shared qw(lock cond_timedwait);

sub timed_dequeue {
  my ($q, $patience) = @_; # XXX revert to $q->dequeue() if $patience is negative?
                           #     $q->dequeue_nb() if $patience is zero?

  my $timelimit = time() + $patience;
  lock(@$q);
  until (@$q) {
    last if !cond_timedwait(@$q, $timelimit);
  }
  return shift if @$q; # We got an element

  # else we timed out.
}

1;

次に、次のようなことを行います。

# main.pl
use threads;
use strict; use warnings;

use Thread::Queue::TimedDequeue;

use constant WORKER_PATIENCE => 10; # 10 seconds

my $queue = Thread::Queue::TimedDequeue->new();
...
sub worker {
  my $item = $queue->dequeue(WORKER_PATIENCE);
  timedout() unless $item;
  ...
}

上記のアプローチは、エンキューまたはその他の誤った値を使用しないことを前提としていることに注意してください。undef

于 2012-07-27T18:29:12.537 に答える
0

アプローチ/構造に問題はありません。「Thread::Queue」にタイムアウト制御を追加するだけです。それは次のいずれかです。

  • タイムアウトを検出するために時間参照を使用しながら、子側からキューをチェックするための「歩留まり」ベースのループを作成します。
  • 「Thread::Queue::Duplex」または「Thread::Queue :: Multiplex」モジュールを使用します。これは少し厄介かもしれませんが、タイムアウト制御を実装しています。
于 2012-07-27T08:34:37.590 に答える