3

Javaでは、スレッドを作成してオブジェクトを共有しているときに、同じオブジェクトメソッドにアクセスするスレッドが必要になることがありますが、同時にそれを実行することはできません。したがって、これを回避するために、以下に示すように、オブジェクトメソッドを同期メソッドとして定義します。

同期インスタンスメソッド:

class class_name {同期タイプmethod_name(){\ statementblock}}

メソッド内のすべてのステートメントが同期ブロックになり、インスタンスオブジェクトがロックになります。つまり、このメソッドを使用するようにスレッドに指示すると、前のスレッドがこのメソッドの使用を終了するまで待機します。Perlでこれを行う方法はありますか?

4

3 に答える 3

5

コンストラクターでミューテックスを作成します。

sub new {
   ...
   my $mutex :shared;
   $self->{mutex_ref} = \$mutex;
   ...
}

メソッドを入力するときにロックします。

sub method {
   my ($self) = @_;
   lock ${ $self->{mutex_ref} };
   ...
}

デモ:

use strict;
use warnings;
use threads;
use threads::shared;
use feature qw( say );

sub new {
   my ($class, $id) = @_;
   my $mutex :shared;
   return bless({
      mutex_ref => \$mutex,
      id        => $id,
   }, $class);
}

sub method {
   my ($self) = @_;
   lock ${ $self->{mutex_ref} };
   say sprintf "%08X %s %s", threads->tid, $self->{id}, "start";
   sleep(2);
   say sprintf "%08X %s %s", threads->tid, $self->{id}, "end";
}

my $o1 = __PACKAGE__->new('o1');
my $o2 = __PACKAGE__->new('o2');

for (1..3) {
   async { my ($o) = @_; $o->method() } $o1;
   async { my ($o) = @_; $o->method() } $o2;
}

$_->join for threads->list();
  • $o1->method同時に実行する2つの呼び出しはありません。
  • を呼び出して$o1->method同時に$o2->method実行できます。

実際、とにかくオブジェクトを共有する場合(これは、async上記のコードに引数としてオブジェクトを渡すことによって行われました)、オブジェクト自体をロックとして使用できます。

use threads::shared qw( shared_clone );

sub new {
   my ($class, ...) = @_;
   return shared_clone(bless({
      ...
   }, $class));
}

メソッドを入力するときにロックします。

sub method {
   my ($self) = @_;
   lock %$self;
   ...
}
于 2012-05-09T15:50:24.070 に答える
2

セマフォを使用してスレッド間でシグナルを送信したり、問題のメソッドが呼び出されたときに共有オブジェクトをロックしたりして、ロックしているスレッドがそのメソッド呼び出しを完了するまで、他のスレッドによる後続の呼び出しをブロックすることができます。

perl のスレッド化は他の言語とは異なるため、 perl でスレッド化を開始する前に、 perl スレッド チュートリアルを読むことを強くお勧めします。

于 2012-05-09T15:06:57.637 に答える