Передача объекта очереди потока как переменной объекта в perl - PullRequest
2 голосов
/ 03 апреля 2019

Я пишу пакет, который принимает входные данные, такие как число потоков, объекты потока :: очереди. Как только объект пакета будет создан, я создам потоки на основе входного аргумента и снимаю очередь с входной очереди в каждом потоке, и каждый поток выполняет простую команду 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 .

1 Ответ

2 голосов
/ 03 апреля 2019

Вы передаете функцию в threads->create без какого-либо контекста объекта, внутри которого они работают. Примерно так должно работать

threads->create( sub { $self->WorkerProcess } );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...