共享线程变量而不使其成为全局变量(Perl) [英] Sharing a thread variable without making it global (Perl)

查看:100
本文介绍了共享线程变量而不使其成为全局变量(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆