Ожидает ли Perl метод присоединения к потоку, чтобы первый поток завершил работу, если я запустил более одного потока? - PullRequest
1 голос
/ 07 декабря 2011
     foreach $name (@project_list)
     {
               # a thread is created for each project
               my $t = threads->new(\&do_work, $name);
               push(@threads, $t);
     } 

    foreach (@threads) {
     my $thrd = $_->join;
     print "Thread $thrd done\n";
    }

    sub do_work {
     # execute some commands here...
    }

Project_list представляет собой список из 40 элементов.Когда я создаю поток для каждого элемента, будет ли метод join ждать завершения первого потока, а затем переходить к следующему и так далее?

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

Пожалуйста, дайте мне знать, если потребуется дополнительная информация.Спасибо.

Ответы [ 3 ]

5 голосов
/ 07 декабря 2011

$_->join ожидает завершения резьбы, обозначенной $_.Поскольку вы нажимаете их по порядку, а foreach просматривает список по порядку, да, вы сначала дождетесь первого потока.

Но это не имеет значения, так как вы ждете все темы до конца.Не имеет значения, будете ли вы сначала ждать самых быстрых финишеров или самых медленных - вы все равно будете ждать всех.

3 голосов
/ 07 декабря 2011

Зачем ждать? Это зависит от объема этапа последующей обработки.

Если этапу постобработки требуется завершить все потоки перед началом работы, то ожидание отдельных потоков неизбежно.

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

В обоих случаях $_->join foreach @threads; - это путь.


Если нет необходимости ждать завершения потоков, используйте команду detach вместо join. Однако любые результаты, которые могут вернуть потоки, будут отброшены.

0 голосов
/ 08 декабря 2011

Основной поток должен жить в течение всех потоков, поэтому вам нужно знать, когда они все будут завершены.Можно сделать очереди или семафоры.Семафоры самые простые:

use Thread::Semaphore;

my $S = Thread::Semaphore->new();


foreach $name (@project_list)
{
    # a thread is created for each project
    my $t = threads->new(\&do_work, $name);
    $S->down_force();                        # take one for each thread
} 

$S->down();                # this blocks until worker threads release one each
print "Thread $thrd done\n";


sub do_work {
    # execute some commands here...
    $S->up();             # here the worker gives one back when done.
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...