【发布时间】:2019-04-03 18:47:36
【问题描述】:
我正在编写一个包,它接受线程计数、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 .
【问题讨论】:
标签: multithreading perl thread-safety