【发布时间】:2016-01-06 08:39:45
【问题描述】:
我正在尝试编写一个使用线程并共享一个变量的简单脚本,但我不想让这个变量对整个脚本都是全局的。下面是一个简化的例子。
use strict;
use warnings;
use threads;
use threads::shared;
my $val:shared;
# Create threads
for my $i (1 .. 5) {
threads->create(\&do_something, $i);
}
# Wait for all threads to complete
map { $_->join(); } threads->list();
# $val is global to the script so this line will work!
print "VAL IS: $val\n";
sub do_something {
my $i = shift;
print "Doing something with thread $i!\n";
{
lock $val;
$val = "SOMETHING IS $i";
print "$val\n\n";
}
}
输出:
用线程 1 做某事! 东西是 1
用线程 2 做一些事情! 某事是 2
用线程 3 做一些事情! 东西是 3
用线程 4 做一些事情! 东西是 4
用线程 5 做某事! 某事是 5
VAL IS: Something is 5
如何在不使整个脚本可以访问$val 的情况下获得这种效果?换句话说,我怎样才能使它尝试打印VAL IS: $val 会失败,但变量仍然会被线程成功共享?
我不能这样定义:
# Create threads
for my $i (1 .. 5) {
my $val:shared;
threads->create(\&do_something, $i);
}
否则我会得到:
全局符号“$val”需要显式封装
什么是词法范围共享变量的正确方法?
【问题讨论】:
-
除非你传入它,否则一个线程怎么可能既是共享的(全局的)又不是全局的?您似乎想要做的是为您的范围创建一个图层。你也试过使用
our($val);吗? -
旁注,
map { $_->join(); } threads->list();=>$_->join() for threads->list();保持你的意图清晰。 -
@Сухой27,谢谢,这更清楚了。
-
@vol7ron,使用
our定义$val将使其更加全球化。我只希望共享变量只能由线程访问,其他任何地方都无法访问。 -
它将它暴露给包,但也许这就是你想要的。我有点全神贯注,所以我不应该发表评论,但这可能属于“你尝试了什么?”类别
标签: multithreading perl scope lexical-scope