Глобальные переменные и fork
Есть глобальная переменная. Как из процесса-потомка, вызванного через fork, записать в неё какое-то значение? (Всё под Windows)
wells, не очень понятно, что есть в данном случае "глобальная переменная".
Даже самый дурацкий замысел можно воплотить мастерски
-
- Сообщения: 1228
- Зарегистрирован: 26 фев 2004, 13:24
- Откуда: Pietari, Venäjä
- Контактная информация:
Никак. Можно конечно иметь один процесс-корень, и ему с помощью IPC передавать и получать от него какие-то данные.Есть глобальная переменная. Как из процесса-потомка, вызванного через fork, записать в неё какое-то значение?
Минусы этого подхода ты конечно понимаешь.
По этому микрософт не стал вводить аналог fork() в WinAPI и всех вынудил использовать трэды.
2B OR NOT(2B) = FF
To AiK: Глобальная переменная - это пременная объявленная в процессе родителе, до вызовf fork. Нужно её обработать после выполнения всех потомков.
wells, если я правильно понял, то waitpid тебе должен помочь.
Правда под виндой никогда не пробовал с fork работать.
Правда под виндой никогда не пробовал с fork работать.
Даже самый дурацкий замысел можно воплотить мастерски
Есть такой код:
Так вот если $threads = 1, всё работает. А при другом значении, например 5, нет!
Код: Выделить всё
use IO::Handle;
use strict;
my $threads = 5;
pipe(READER, WRITER);
autoflush WRITER;
my ($pid, $line);
my $threads = 5;
for (my $i = 1; $i <= ($threads); $i++) {
if ($pid = fork) {
close WRITER;
chomp($line = <READER> );
#print $line;
close READER;
waitpid($pid,0);
}
else {
die "cannot fork: $!" unless defined $pid;
close READER;
print WRITER "4"; #This value will be sent to $line
close WRITER; # this will happen anyway
exit;
}
}
print $line;
Так вот если $threads = 1, всё работает. А при другом значении, например 5, нет!
Перенеси pipe(READER, WRITER) в цикл.
Код: Выделить всё
use IO::Handle;
use strict;
#my $threads = 5;
autoflush WRITER;
my ($pid, $line);
my $threads = 5;
for (my $i = 1; $i <= ($threads); $i++) {
pipe(READER, WRITER);
if ($pid = fork) {
close WRITER;
chomp($line = <READER> );
#print $line;
close READER;
waitpid($pid,0);
}
else {
die "cannot fork: $!" unless defined $pid;
close READER;
print WRITER "4"; #This value will be sent to $line
close WRITER; # this will happen anyway
exit;
}
}
print $line;
В том то и вопрос, что если в процессе потомке что-то делать, то распаралеливание процессов не получается. Например если в ветку else засунуть
то весь скрипт выполняется в пять раз дольше!!!
Вообщем есть следующий скрипт:
Так вот при $threads = 1 он выполняется 6 секунд, а при = 5, скрипт работает все 30 секунд.
Получается, что процессы-потомки работают последовательно.
Если убрать всё, что связанно с pipe при любом значении $threads ( вплоть до 50)
скрипт выполняется за теже 6 секунд.
Вот в чём собака порылась!
Код: Выделить всё
my $i = 0;
for ($i; $i<=10 ; $i++) {
Time::HiRes::sleep(1.0);
}
Вообщем есть следующий скрипт:
Код: Выделить всё
use strict;
use IO::Handle;
use Benchmark;
my $tmStamp1 = new Benchmark;
#/////////////////////////////////////////////////////////////////////////////////
my $threads = 5;
my @pids;
my $isExit = 0;
#/////////////////////////////////////////////////////////////////////////////////
print "$isExit\n";
print "start\n";
for (my $i = 1; $i <= ($threads); $i++) {
pipe(PARENT_RD, CHILD_WR);
autoflush CHILD_WR;
my $pid;
if ($pid = fork) {
close CHILD_WR;
chomp($isExit = <PARENT_RD>);
close PARENT_RD;
push(@pids,$pid);
}
else {
die "cannot fork: $!" unless defined $pid;
my $i = 0;
for ($i; $i<=5; $i++) {
Time::HiRes::sleep(1.0);
}
close PARENT_RD;
print CHILD_WR "1";
close CHILD_WR;
exit;
}
}
for (my $l = 0; $l <= ($threads-1); $l++) {
print "$pids[$l]\n";
waitpid($pids[$l], 0);
}
print "stop\n";
print "$isExit\n";
#/////////////////////////////////////////////////////////////////////////////////
my $tmStamp2 = new Benchmark;
my $tmDiffer = timediff($tmStamp1, $tmStamp2);
print timestr($tmDiffer);
Получается, что процессы-потомки работают последовательно.
Если убрать всё, что связанно с pipe при любом значении $threads ( вплоть до 50)
скрипт выполняется за теже 6 секунд.
Вот в чём собака порылась!
В этом местеродительский процесс ждет пока ты ему чего-нибудь напишешь и дальше не выполняется. Поставь цикл задержки после отправки сообщения, и все будет выполняться 6 секунд
Код: Выделить всё
chomp($isExit = <PARENT_RD>);
Код: Выделить всё
else {
die "cannot fork: $!" unless defined $pid;
close PARENT_RD;
print CHILD_WR "1";
close CHILD_WR;
my $i = 0;
for ($i; $i<=5; $i++) {
Time::HiRes::sleep(1.0);
}
exit;
}
Это не прокатит, так как задержка это эмуляция работы достаточно длительного куска кода, который по результатам своей работы и пишет pipe! А через Thread нельзя ли это всё реализовать?