LINUX.ORG.RU

Perl и мультизадачность

 , , ,


0

1

Вопрос к бывалым перловикам, которые не гнушаются использовать fork(). Допустим есть несколько функций (myfunc1, myfunc2 и myfunc3). Каждая из этих функций должна работать в отдельном процессе. Только после того, когда отработают все функции - программа должна завершиться. Но у меня она остается висеть и вообще, видимо я что-то делаю не так.

...
use POSIX ":sys_wait_h";

$SIG{CHLD} = sub {1 while( waitpid(-1, WHONANG) > 0 )};

sub myfunc1 {print "Hello 1\n";}

sub myfunc2 {print "Hello 2\n";}

sub myfunc3 {print "Hello 3\n";}

for ((\&myfunc1, \&myfunc2, \&myfunc3)) {
	if (my $pid = fork()) {
 		$_->();
 		waitpid($pid, 0);
 	}
}

print "THE END\n\n";

Все висит - ничего не помагает. Подскажите, как поправить код, чтобы оно заработало как надо?


$ perl script.pl
Hello 1
Hello 2
Hello 3
THE END

THE END

Hello 3
THE END

THE END

Hello 2
Hello 3
THE END

THE END

Hello 3
THE END

THE END
$ perl -v
This is perl 5, version 22, subversion 2 (v5.22.2) built for x86_64-linux-thread-multi
...
Deleted
()
Ответ на: комментарий от Deleted

Тоже не то. THE END - должен быть только один раз, когда ВСЕ форки либо отработают норм, либо умрут.

djnoob
() автор топика

Могу и ошибаться конечно, но когда ты запускаешь fork() - то копируется сам процесс, отсюда и массовый 'THE END' в коменте ниже. Сделай проверку на то где ты находишься после форка, если мне память не изменяет - то pid форка будет "-1", и если '-1' тогда делай exit после нужных действий. Нет exit - получай кучу процессов каждый из которых заканчивается вот этим:

print «THE END\n\n»;

Kronick
()
Ответ на: комментарий от Kronick

В общем ладно, держи:

use POSIX ":sys_wait_h";

$SIG{CHLD} = sub {1 while( waitpid(-1, WHONANG) > 0 )};

sub myfunc1 {print "Hello 1\n";}

sub myfunc2 {print "Hello 2\n";}

sub myfunc3 {print "Hello 3\n";}

for ((\&myfunc1, \&myfunc2, \&myfunc3)) {
	if (my $pid = fork()) {
 		# $_->();
 		print "Main process pid = '$pid'\n";
 		waitpid($pid, 0);
 	}
 	else {
		print "Fork process pid = '$pid'\n";
		$_->();
		
		exit 0;
	}
}

Ну и аутпут:

Main process pid = '31635'
Fork process pid = '0'
Hello 1
Main process pid = '31636'
Fork process pid = '0'
Hello 2
Main process pid = '31637'
Fork process pid = '0'
Hello 3

К синтаксису можно придраться конечно, но я так, от руки накидал, думал суть будет понятна

Kronick
()
Ответ на: комментарий от Kronick

сколько денег тс должен за твою работу? не стесняйся. нехрен работать за других, терпилка.

anonymous
()
Ответ на: комментарий от anonymous

Да нисколько, мне тут тоже помогали, и возможно помогут еще с чем-нибудь

Kronick
()
Ответ на: комментарий от Kronick

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

waitpid'ы нужны за телом цикла.

DRVTiny ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.