我有这个测试脚本:
use threads;
start();
sub start {
my $A = threads->create(\&A);
my $B = threads->create(\&B);
sleep;
}
sub A {
while (1) {
print "A\n";
sleep(1);
}
}
sub B {
while (1) {
print "B\n";
sleep(1);
}
}
此输出将是(每秒一次,永远):
A
B
我正在尝试使用面向对象的包:
package Test;
use threads;
sub new { my ($class) = @_;
my $self = {
A => undef,
B => undef
};
bless $self, $class;
return $self;
}
sub start { my ($self) = @_;
$self->{A} = threads->create(\&{$self->A});
$self->{B} = threads->create(\&{$self->B});
sleep;
}
sub A { my ($self) = @_;
while (1) {
print "A\n";
sleep(1);
}
}
sub B { my ($self) = @_;
while (1) {
print "B\n";
sleep(1);
}
}
1;
然后:
use Test;
my $test = Test->new();
$test->start();
此输出将是(每秒一次,永远):
A
似乎代码卡在第一个线程上。我很难理解Perl中线程背后的逻辑。如何从面向对象的包中的第一个脚本复制相同的行为?
答案 0 :(得分:1)
$self->A
是一个永不返回的方法调用,因此\&{$self->A}
也永远不会返回,您永远无法定义$self->{B}
。
一种方法是
$self->{A} = threads->create( sub { $self->A } );
$self->{B} = threads->create( sub { $self->B } );
表达式sub { $self->A }
定义一个(匿名)子例程并将其传递给threads::create
方法,但不调用子例程,允许程序继续。
答案 1 :(得分:0)
这是一个更有趣的测试脚本。
您应该通过在匿名子例程中关闭实例来调用对象实例上的方法。
我不知道您希望通过threads->create{\&{$self->A}};
在调用create
之前,调用$self->A
必须返回一个值。但是,它的设计永远不会回归。但是,那么,你应该在你的create
调用中使用大括号。所以,至少可以说这很令人困惑。
另外,请不要试图通过牺牲代码的可读性来保存行。
package Test;
use strict;
use warnings;
use threads;
sub new {
my $class = shift;
return bless { A => undef, B => undef } => $class;
}
sub start {
my $self = shift;
$self->{$_} = threads->create(sub { $self->$_ }) for qw(A B);
$self->{$_}->join for qw(A B);
return;
}
sub A {
my $i = 'A';
while (10 > time - $^T) {
print "$i\n";
$i++;
sleep 1;
}
}
sub B {
my $i = '0';
while (10 > time - $^T) {
print "$i\n";
$i++;
sleep 1;
}
}
package Main;
use strict;
use warnings;
my $test = Test->new;
$test->start;