0

线程有问题。使用类实例方法作为子例程创建线程时不断出错。method 和 params 变量是根据其他东西设置的,所以我必须这样调用类实例方法。没有线程,它工作得很好。无法找出为线程创建指定它的正确方法:

my $instance = someclass->new();
my $method = 'get';
my $params = { 'abc' => 123 };
my $thread = threads->create($instance->$method,$params);

这给了我错误“不是代码参考”。我认为这可能实际上是调用该方法,并使用 return 作为参数。好的,试过这个:

my $thread = threads->create(\&{$instance->$method},$params);

这给了我错误“不是子程序引用”。我将不胜感激这方面的任何帮助。

4

2 回答 2

4
my $thread = threads->create(sub { $instance->$method(@_) }, $params);

或者,您也可以将实例和方法传递给第一个参数:

package SomeClass;

sub new {
    my $class = shift;
    bless { args => [ @_ ] };
}

sub get {
    my $self = shift;
    my $args = shift;
    return join(" ", @{ $self->{args} }, $args->{abc});
}

package main;

use 5.012;
use threads;

my $x = SomeClass->new("An instance");

threads->create(sub { say $x->get(@_) }, {'abc' => 123 })->join;

threads->create(
    sub {
        my $instance = shift;
        my $method = shift;
        say $instance->$method(@_);
    }, $x, 'get', { 'abc' => 123 }
)->join;

事实上,我更喜欢后者,以避免关闭$instance.

于 2013-04-11T18:54:02.253 回答
1

调用不带括号的方法与调用不带参数的方法是一样的:

$foo->bar eq $foo->bar()

要创建 coderef,您可以指定包装方法调用的 lambda,例如

threads->create(sub{ $instance->get($params) })

(请参阅 Sinan Ünürs 的回答),或者您可以使用通用can功能。

can方法解析方法的方式与调用方法的解析方式相同,如果找到该方法,则返回该方法的 coderef,或者返回undef. 这使其可用作布尔测试。

请注意,方法只是子程序,第一个参数是调用者(对象):

my $code = $instance->can($method) or die "Can't resolve $method";
threads->create($code, $instance, $params);

但是,can对于使用AUTOLOAD.

于 2013-04-11T19:04:08.033 回答