Perl: завершить поток и получить лучший результат - PullRequest
3 голосов
/ 24 августа 2011

Я довольно новичок в потоках Perl, поэтому я хотел бы знать правильный способ сделать это в Perl:

for $input (@inputs) {
  push @threads, start_thread($input);
}

for $thread (@threads) {
   wait_for_external_event();
   $thread->kick_thread_out_of_loop();
   $result = $thread->result();
   print $result;
}

sub my_thread {
  my $input = shift;
  while(1) {
    my $result = compute($best_result_so_far,$input);
    if($result > $best_result_so_far) {
      $best_result_so_far = $result;
    }
  }
  # The thread got kicked out of the loop
  return $best_result_so_far;
  do_some_cleanup_that_is_slow();
  exit thread;
}

У меня такое чувство, что способ выкинуть поток из цикла вычисленийиспользуя сигналы и обработчик сигналов в потоке.Но, возможно, есть даже более красивые способы сделать это.Мне нужна помощь в том, как именно это реализовать, и особенно в том, как я могу вернуть $ best_result_so_far и после возврата выполнить медленную очистку.Очень важно, чтобы мне не пришлось ждать очистки, прежде чем я смогу получить результат.

--- edit ---

Я посмотрел учебник, и яне удалось найти примеры общения с запущенными потоками («объединение» только умирает потоками).Могу ли я получить результат обратно из запущенного потока, например:

for $input (@inputs) {
  push @threads, start_thread($input);
}

for $thread (@threads) {
   wait_for_external_event();
   $result = $thread->result();
   $thread->kill("KILL");
   print $result;
}

package ThreadObj;

sub my_thread {
  my $self = shift;
  my $input = shift;

  local $SIG{KILL} = sub {
    do_slow_cleanup();
    threads->exit();
  };

  while(1) {
    my $result = compute($best_result_so_far,$input);
    if($result > $self->{'best_result_so_far'}) {
      $self->{'best_result_so_far'} = $result;
    }
  }
}

sub result {
  my $self = shift;
  wait until (defined $self->{'best_result_so_far'});
  return $self->{'best_result_so_far'};
}

Ответы [ 2 ]

1 голос
/ 24 августа 2011

Я бы использовал одну или две структуры данных для связи, где каждый поток использует свой уникальный идентификатор для доступа к записи в общем хеше для хранения своих текущих результатов. Используйте второй хеш, таким же образом, как флаг, чтобы сигнализировать потоку, что пора выходить - или один общий скаляр на случай, если все потоки должны выйти одновременно. Вместо бесконечного цикла вы выполняете цикл до тех пор, пока флаг не установлен.

1 голос
/ 24 августа 2011

Насколько мне известно, невозможно вернуть результат из потока и отложить очистку потока на более поздний срок.

Если $best_result_so_far является общим для всех потоков (IOW, есть только один лучший результат), тогда threads::shared и семафоры могут помочь (хотя и с затратами на производительность). См. perldoc perlthrtut для некоторых хороших примеров для начинающих.

Такое ощущение, что эта проблема больше подходит для парадигмы программирования на основе событий. Может ли Coro::AnyEvent быть подходящим инструментом для этой работы?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...