分类: Python/Ruby
2012-11-29 13:50:51
点击(此处)折叠或打开
输出的结果
1 2 3 4 5 6 7 | $VAR1 = \'2000'; $VAR1 = [ '2000' ]; $VAR1 = { 'test' => '2000' }; |
从上面,我们可以看出,在使用共享变量是,我们一定要使用一个 lock 来锁定当前需要共享的变量,这需要一个排它性.不然很容易出问题,不锁的话,会出什么问题啦,我们来看下面的例子,出掉锁以后会怎么样.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #!/usr/bin/perl use strict; use threads; use threads::shared; use Data::Dumper; my $val : shared; # 共享变量 my %hash : shared; # 共享数组 my @array : shared; # 共享哈希 my $t1 = threads->create(\&test1); my $t2 = threads->create(\&test2); $t1->join; # 回收 t1 的线程 $t2->join; print Dumper(\$val); print Dumper(\@array); print Dumper(\%hash); sub test1 { for ( 1 .. 1000 ){ $val++; $array[0]++; $hash{test}++; } } sub test2 { for ( 1 .. 1000 ){ $val++; $array[0]++; $hash{test}++; } } |
输出的结果很神奇,象这个样子
1 2 3 4 5 6 7 | $VAR1 = \'1830'; $VAR1 = [ '1922' ]; $VAR1 = { 'test' => '1922' }; |
本来正常的结果是 2000 的,现在好了,都是乱的,主要是因为,当进程 test1 在使用共享变量时, test2 也同时拿到这个变量,本来每个加一起,合起来是 2000,但因为拿到相同的数字相加,所以结果就乱了.所以在使用线程时,一定要非常注意共享变量加锁.
在 Perl 中有个子函数的 lock ,也有对象的方法锁,使用的方法是
子函数的锁
sub frob : locked {
# 和以前一样
}
对象方法的锁
sub frob : locked method {
# 和以前一样
}
注意,上面的方法现在 Perl 中不可用了.但书中因为历史的原因,还写着这样的方法,我们可以使用下面的方法来测试,就知道结果了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | #!/usr/bin/perl use strict; use threads; use threads::shared; use Data::Dumper; my $val : shared; # 共享变量 my %hash : shared; # 共享数组 my @array : shared; # 共享哈希 my $t1 = threads->create(\&test1); my $t2 = threads->create(\&test2); $t1->join; # 回收 t1 的线程 $t2->join; print Dumper(\$val); print Dumper(\@array); print Dumper(\%hash); sub test1 : locked { for ( 1 .. 1000 ){ $val++; $array[0]++; $hash{test}++; } } sub test2 : locked { for ( 1 .. 1000 ){ $val++; $array[0]++; $hash{test}++; } } |
这样输出的结果,会和没有加锁时会是一样的.