共享线程变量而不使其成为全局变量(Perl) [英] Sharing a thread variable without making it global (Perl)
问题描述
我正在尝试编写一个使用线程并共享一个变量的简单脚本,但是我不想将此变量设置为整个脚本的全局变量.下面是一个简化的示例.
I'm trying to write a simple script that uses threads and shares a variable, but I don't want to make this variable global to the whole script. Below is a simplified example.
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
Doing something with thread 1! SOMETHING IS 1
在线程2上做一些事! 大概是2
Doing something with thread 2! SOMETHING IS 2
在线程3上做一些事! 大概是3
Doing something with thread 3! SOMETHING IS 3
在线程4上做一些事情! 大概是4
Doing something with thread 4! SOMETHING IS 4
用线程5做某事! 大概是5
Doing something with thread 5! SOMETHING IS 5
VAL IS:大约是5
VAL IS: SOMETHING IS 5
如何在不使整个脚本可访问$val
的情况下获得此效果?换句话说,如何使尝试打印VAL IS: $val
失败,但是线程仍将成功共享该变量?
How can I get this effect without making $val
accessible to the whole script? In other words, how can I make it so attempting to print VAL IS: $val
will fail, but the variable will still be successfully shared by the threads?
我不能这样定义它:
# Create threads
for my $i (1 .. 5) {
my $val:shared;
threads->create(\&do_something, $i);
}
不然我会得到:
全局符号"$ val"需要显式包
Global symbol "$val" requires explicit package
用词法定义共享变量的正确方法是什么?
What is the right way to lexically scope a shared variable?
推荐答案
将对它的引用作为参数传递.
Pass a reference to it as an argument.
sub do_something {
my ($id, $lock_ref) = @_;
print("$id: Started\n");
{
lock $$lock_ref;
print("$id: Exclusive\n");
sleep(1);
}
print("$id: done.\n");
}
{
my $lock :shared;
for my $id (1..5) {
async { do_something($id, \$lock); };
}
}
或对其进行范围限定,以便只有辅助工作人员才能看到它.
Or scope it so only the worker subs can see it.
{
my $lock :shared;
sub do_something {
my ($id) = @_;
print("$id: Started\n");
{
lock $lock;
print("$id: Exclusive\n");
sleep(1);
}
print("$id: done.\n");
}
}
for my $id (1..5) {
async { do_something($id); };
}
这篇关于共享线程变量而不使其成为全局变量(Perl)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!