如何在Perl中存储调用之间的每个线程状态?

如何在Perl中存储调用之间的每个线程状态?,perl,multithreading,thread-safety,Perl,Multithreading,Thread Safety,现在根据我在Perl下的理解,除非显式共享,否则所有数据都是私有的 我想写一个函数,在调用之间存储每个线程的状态。我假设默认情况下所有数据都是线程私有的副作用允许我使用如下闭包: #!/usr/bin/perl -w use strict; use threads; { # closure to create local static variable my $per_thread_state = 0; sub foo { my $inc = shift;

现在根据我在Perl下的理解,除非显式共享,否则所有数据都是私有的

我想写一个函数,在调用之间存储每个线程的状态。我假设默认情况下所有数据都是线程私有的副作用允许我使用如下闭包:

#!/usr/bin/perl -w

use strict;
use threads;

{ # closure to create local static variable
    my $per_thread_state = 0;

    sub foo {
        my $inc = shift;
        $per_thread_state += $inc;

        return $per_thread_state;
    }
}

my $inc = 0;

threads->create(
    sub { 
        my $inc = shift;
        my $i = $inc; 
        while (--$i) { 
            threads->yield(); 
            print threads->tid().":".foo($inc)."\n";
        }
    }, $inc
) while (++$inc < $ARGV[0]);

$_->join() foreach threads->list();

一切打印得井井有条。如果有必要的话,我会使用Ubuntu9.04。

如果您运行的是Perl 5.9.4+,那么这似乎是使用关键字的一个很好的候选者。如果启用了
state
,则只有
foo()
子例程才能修改
$per\u thread\u state
的值

以下是方法:

use feature 'state';

sub foo {
    state $per_thread_state;
    my $inc = shift;
    $per_thread_state += $inc;
    return $per_thread_state;
}
记住启用
状态
尽管(从):

从Perl5.9.4开始,您可以用state关键字代替my来声明变量。但是,要想实现这一点,您必须事先启用该特性,或者使用特性pragma,或者在一行程序中使用-E


perlsub也有一节介绍。您所做的似乎很好。

您创建每个线程状态的方法是正确的

将Perl的线程视为处理IPC和分叉进程的更方便的方法通常会有所帮助。每次调用
threads->create(…)
都会克隆当前解释器以及解释器中的所有内容,因此每个线程都将获得各自独立的
foo()
$per\u thread\u state
副本。当您加入一个线程时,您可以传回一个值,但是线程解释器状态中的所有其他内容都将被销毁


线程按创建顺序运行主要是由于Perl和操作系统中的实现细节(主要是因为它们各自的执行时间低于操作系统的最短执行时间片)。要交错线程,您可以使用
sleep
而不是屈服(或者让线程做一些实际工作)。

是的,我希望与旧的5.9.4版本之前的PERL保持兼容。为了确保
BEGIN
仅在我将闭包放在“主”线程的代码之后的文件末尾时才需要,对吗?有效地说,是的,尽管我会将
BEGIN
放在anyway@Zaid:作为一般规则,我通常只在24小时后接受答案。有点耐心:-)时间片是有道理的。我在
foo
中添加了一个乘法和除法,循环100次,现在我看到了更加一致的交错。@Eric:我想你可以回答另一个问题:
use feature 'state';

sub foo {
    state $per_thread_state;
    my $inc = shift;
    $per_thread_state += $inc;
    return $per_thread_state;
}