Не все потоки завершаются, возможно, из-за того, что стандартный вывод не заблокирован

#multithreading #perl

#многопоточность #perl

Вопрос:

Я экспериментирую с потоками в perl. Следующий код в основном создает n потоков и назначает им одну и ту же функцию (которую они должны выполнять параллельно).

Поворот: функция просто что-то печатает. Это означает, что они не могут делать это параллельно. Честно говоря, меня это устраивает, так как я только начинаю что-то делать с ними, однако, похоже, не все темы заканчиваются. Я полагаю, это связано с тем, что я не заблокировал ЗППП, и именно поэтому возникают некоторые конфликты. Возможно, причина не в этом. В любом случае разное количество потоков не завершается каждый раз.

Если я прав, как я могу заблокировать стандартный вывод (я получаю сообщение об ошибке при попытке использовать функцию блокировки)?

Если я ошибаюсь, почему все потоки не завершаются и как я могу это исправить?

Кодекс:

 use strict;
use threads ('yield',
                 'stack_size' => 64*4096,
                 'exit' => 'threads_only',
                 'stringify');
use threads::shared;


sub PrintTestMessage()
{
    print "Hello worldn";
}

my @t;
push @t, threads->new(amp;PrintTestMessage) for 1..10;
 

Я получаю 10 раз привет, мир, однако после завершения программы я получаю другой результат:

 Perl exited with active threads:
    1 running and unjoined
    9 finished and unjoined
    0 running and detached
Perl exited with active threads:
    8 running and unjoined
    2 finished and unjoined
    0 running and detached
Perl exited with active threads:
    5 running and unjoined
    5 finished and unjoined
    0 running and detached
 

Почему не все потоки завершены? (несоединимое связано с тем, что я никогда не присоединяюсь к ним в коде, так что это ожидаемо)

Ответ №1:

Вы должны присоединиться к потокам, иначе основной поток может (как в вашем примере) завершиться раньше своих дочерних потоков,

 $_->join for @t;
 

От perldoc threads ,

$ thr-> join()

Это будет ждать, пока соответствующий поток завершит свое выполнение. Когда поток завершится, ->join() вернет возвращаемое значение (значения) функции точки входа.

Комментарии:

1. Так вот в чем проблема. Спасибо за объяснение!

2. Или $_->join for threads->list(); . Нет необходимости создавать массив.