【问题标题】:Passing a thread queue object as a object variable in perl在 perl 中将线程队列对象作为对象变量传递
【发布时间】: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


    【解决方案1】:

    您正在将一个函数传递给threads-&gt;create,而没有它们正在使用的对象的任何上下文。像这样的东西应该可以工作

    threads->create( sub { $self->WorkerProcess } );
    

    【讨论】:

    • 或async { $self-&gt;WorkerProcess };
    猜你喜欢
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 2022-12-19
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多