我在perl中编写了一个执行多线程的脚本,然后尝试将其转换为对象。但是,我似乎无法弄清楚如何锁定成员变量。我最接近的是:
#!/usr/bin/perl
package Y;
use warnings;
use strict;
use threads;
use threads::shared;
sub new
{
my $class = shift;
my $val :shared = 0;
my $self =
{
x => \$val
};
bless $self, $class;
is_shared($self->{x}) or die "nope";
return $self;
}
package MAIN;
use warnings;
use strict;
use threads;
use threads::shared;
use Data::Dumper;
my $x = new Y();
{
lock($x->{x});
}
print Dumper('0'); # prints: $VAR = '0';
print Dumper($x->{x}); # prints: $VAR = \'0';
print "yes\n" if ($x->{x} == 0); # prints nothing
#print "yes\n" if ($$x->{x} == 0); # dies with msg: Not a SCALAR reference
my $tmp = $x->{x}; # this works. Must be a order of precedence thing.
print "yes\n" if ($$tmp == 0); # prints: yes
#++$$x->{x}; # dies with msg: Not a SCALAR reference
++$$tmp;
print Dumper($x->{x}); # prints: $VAR = \'1';
这允许我锁定成员var x
,但这意味着我需要2个成员变量,因为实际的成员var实际上不能通过赋值来操作,递增它等我甚至无法对它进行测试。
修改:
我在想我应该重命名这个问题“你如何取消引用perl中的成员变量?”因为问题似乎归结为此。使用$$x->{x}
语法无效,您不能强制使用括号的优先级规则。即$($x->{x})
不起作用。使用临时工作,但这是一个麻烦。
答案 0 :(得分:2)
我没有得到你想要做的线程和锁定,但是你使用引用的方式有一些简单的错误。
$x->{x}
是对标量的引用,因此表达式
$x->{x} == 0
++$$x->{x}
看起来都很可疑。 $$x->{x}
被解析为{$$x}->{x}
(取消引用$x
,然后将其视为哈希引用,并使用键x
查找该值。我想你的意思是说
${$x->{x}} == 0
++${$x->{x}}
其中${$x->{x}}
表示将$x
视为哈希引用,在该哈希中查找键x
的值,然后取消该值。