Как я могу мгновенно убить поток Perl, не убивая всю программу? - PullRequest
5 голосов
/ 09 августа 2011

Когда я использую exit или die, это убивает всю программу.

foreach my $t (threads->list())
{
    $t->exit;
    $count++;
}

Usage: threads->exit(status) at main.pl line 265
Perl exited with active threads:
        9 running and unjoined
        0 finished and unjoined
        0 running and detached

Есть идеи?

Ответы [ 3 ]

7 голосов
/ 09 августа 2011

Чтобы игнорировать поток, который выполняется, верните элемент управления и отбросьте все, что он может выводить, правильный метод для использования - detach, а не exit.

См. perldoc perlthrtut - Игнорирование потока .


perldoc threads объясняет, почему код завершается:

threads->exit()

При необходимости можно завершить поток в любое время, вызвав threads->exit(). Это заставит поток вернуть undef в скалярный контекст или пустой список в контексте списка. Когда звонят из main thread, ведет себя так же, как exit(0).


Может быть способ достижения мгновенного завершения (у меня не работает в Windows):

use threads 'exit' => 'threads_only';

Это глобально переопределяет поведение вызова по умолчанию exit() внутри потока, и эффективно заставляет такие вызовы вести себя одинаково как threads->exit(). Другими словами, с этой настройкой exit() вызывает завершение только потока. Из-за его глобального эффект, этот параметр не должен использоваться внутри модулей или тому подобное. Этот параметр не влияет на основной поток.

Документация также предлагает другой способ, используя метод set_thread_exit_only (опять же, у меня не работает в Windows):

$thr->set_thread_exit_only(boolean)

Это можно использовать для изменения поведения только выходного потока для потока после того, как он был создан. С истинным аргументом exit() вызовет только нить для выхода. С ложным аргументом exit() будет прекратить заявку. Этот поток не затрагивает основной поток.


В приведенном ниже примере используется сигнал kill для завершения потока $unwanted:

use strict;
use warnings;
use threads;

my $unwanted = threads->create( sub {
                                      local $SIG{KILL} = sub { threads->exit };
                                      sleep 5;
                                      print "Don't print me!\n";
                                    } );

my $valid    = threads->create( sub {
                                      sleep 2;
                                      print "This will print!\n";
                                    } );

$unwanted->kill('KILL')->detach;   # Kills $thr, cleans up

$valid->join;                 # sleep 2, 'This will print!'
3 голосов
/ 10 августа 2011

Если вы хотите убить поток, вы убиваете его с помощью $thread->kill. Если вы хотите отказаться от потока, но оставить его работающим, используйте $thread->detach. threads->exit вызывает выход потока current ; он не воспринимает поток как инвокант.

0 голосов
/ 09 августа 2011

В сообщении об ошибке говорится, что $t->exit требует аргумента. Попробуйте дать ему один. (perldoc Threads, кажется, говорит, что это не так, но я не знаю, какой пакет вы используете.)

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