我正在编写一个程序包,它接受诸如线程数,thread :: Queue对象之类的输入。 创建包对象后,我将基于输入参数创建线程,并在每个线程中使输入队列出队,并且每个线程执行一个简单的unix命令,例如对服务器执行ping操作(为保持简单而进行了更改)。 下面是代码:
my $failed_q = Thread::Queue -> new();
my $success_q = Thread::Queue -> new();
my $process_q = Thread::Queue -> new();
package WorkerThreads;
sub new {
my $class = shift;
my $self = {
_ThreadCount => shift,
_FidQueue => shift,
_SuccessQueue => shift,
_FailedQueue => shift,
};
bless $self, $class;
return $self;
}
sub WorkerProcess
{
my ($self)=@_;
while ( my $fid = $self->{_FidQueue} -> dequeue() )
{
chomp ( $fid );
print threads -> self() -> tid(). ": pinging $fid\n";
my $result = `/bin/ping -c 1 $fid`;
if ( $? ) { $self->{_FailedQueue} -> enqueue ( $fid ) }
else { $self->{_SuccessQueue} -> enqueue ( $fid ) ; }
sleep 1;
}
print threads -> self() -> tid(). ":\n";
}
sub CreateThreads
{
my ($self)=@_;
my $Num_of_threads=$self->{_ThreadCount};
for ( 1..$Num_of_threads )
{
threads -> create ( \&WorkerProcess );
}
}
sub StartThreads
{
my ($self)=@_;
foreach my $thr ( threads -> list() )
{
$thr -> join();
}
}
sub PrintResult
{
my ($self)=@_;
while ( my $fid = $self->{_FailedQueue} -> dequeue_nb() )
{
print "$fid failed to ping\n";
}
#collate results. ('synchronise' operation)
while ( my $fid = $self->{_SuccessQueue} -> dequeue_nb() )
{
print "$fid Ping Succeeded\n";
}
}
sub ProcessRequest
{
my ($self)=@_;
$self->CreateThreads(@_);
$self->StartThreads(@_);
$self->PrintResult(@_);
}
package main;
#insert tasks into thread queue.
open ( my $input_fh, "<", "server_list" ) or die $!;
$process_q->enqueue( <$input_fh> );
close ( $input_fh );
my $Workers;
$Workers=WorkerThreads->new(
10,
$process_q,
$success_q,
$failed_q
);
$Workers->ProcessRequest();
当我尝试在while循环中出队队列未定义时遇到错误。所以我有这样的疑问,比如我们可以将线程队列对象作为参数传递给程序包。
Thread 1 terminated abnormally: Can't call method "dequeue" on an undefined value at .
答案 0 :(得分:2)
您要将函数传递到threads->create
中,而没有它们在其中处理哪个对象的任何上下文。这样的事情应该起作用
threads->create( sub { $self->WorkerProcess } );