Вы можете запустить Perl в режиме strace, и вы обнаружите, что жизни ваших детей довольно коротки, и выглядят так:
close(3) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff753b3a10) = -1 EINVAL (Invalid argument)
lseek(4, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
fstat(4, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
dup2(4, 1) = 1
dup(4) = 3
fcntl(4, F_GETFD) = 0x1 (flags FD_CLOEXEC)
dup2(3, 4) = 4
fcntl(4, F_SETFD, FD_CLOEXEC) = 0
close(3) = 0
fcntl(1, F_SETFD, 0) = 0
write(2, "[30629] child alive with 75000 e"..., 39) = 39
brk(0x3582000) = 0x3582000
write(1, "START: 1\n", 9) = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
Вот почему:
pipe $parent_from_child, $child_to_parent[$proc] or die "pipe failed - $!";
Вы использовали массив с неверным аргументом для конвейера.Вы должны держать все стороны read открытыми в родительском элементе.Вместо этого вы установили массив, чтобы родитель мог оставить все стороны записи открытыми (но затем в родительском блоке вы немедленно закрыли сторону записи).Поэтому в следующий раз в вашем цикле pipe
создаст новый дескриптор, назначит его на $parent_from_child
.Таким образом, старое значение больше не имеет ссылок, и Perl очищает его, то есть закрывает дескриптор файла.Так что ваши дети, за исключением последнего, все умирают от SIGPIPE.
Я думаю, у вас сложилось впечатление, что вы можете повторно использовать этот дескриптор чтения и просто назначить ему несколько дескрипторов записи.Ты не можешьpipe
всегда создает новый дескриптор чтения и новый дескриптор записи.
Если вы действительно хотите использовать один и тот же дескриптор чтения (вероятно, нет, это приведет к повреждению, когда чередуется вывод двух клиентов), просто создайте его один раз, вне цикла.Все дети наследуют один и тот же дескриптор записи через fork
.Скорее всего, вам нужно по одному на каждого ребенка, и вам придется использовать цикл select
, чтобы увидеть, какие из них имеют выходную информацию, и прочитать их.
В качестве альтернативы, я уверен, что CPAN имеет готовыйрешение (или десять) для вас.