При работе с распределенной базой данных иногда возникает необходимость выполнить один и тот-же запрос на каждом сегменте базы. По-очереди - долго, хочется параллельно.
Для решения этой и подобных задач написал маленький модуль BGS - Background execution of subroutines in child processes. Модуль позволяет упростить выполнение подпрограмм в дочерних процессах, ожидание их завершения и возврат результатов работы подпрограмм из дочерних процессов в основной.
Пример использования:
use BGS; my @foo; foreach my $i (1 .. 2) { bgs_call { # child process return "Start $i"; } bgs_back { # callback subroutine my $r = shift; push @foo, "End $i. Result: '$r'.\n"; }; } bgs_wait(); print foreach @foo;
Код, который будет выполняться в дочерних процессах, помещается в блок bgs_call.
Код, который выполниться в основном процессе, при завершении bgs_call, находиться в блоке bgs_back. Ответ bgs_call (скаляр или ссылка, но не список) передается в bgs_back в качестве аргумента.
Механизм запускается командой bgs_wait. Не забудьте перед созданием дочерних процессов, закрыть все соединения к базе. Почему это желательно сделать, смотрите в заметке "Отцы и дети или perl, fork и деструкторы".
Внимание, код, который будет вызываться из bgs_call, на данный момент ничего не должен печатать на STDOUT! Надо, все таки, собраться и устранить этот недостаток. А может еще добавить timeout ожидания?
Кстати, на CPAN недавно обнаружил модуль Parallel::SubFork с похожим функционалом.
Судя по датам BGS и Parallel::SubFork писались приблизительно в одно время. :-)
Оригинал: http://laziness-impatience-hubris.blogspot.com/2008/10/background-execution-of-subroutines-in.html.
