コンストラクターでミューテックスを作成します。
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;
...
}