Запись в файловый дескриптор НЕ атомная для STDOUT и STDIN.Существуют особые случаи для таких вещей, как fifos, но это не ваша текущая ситуация.
Когда он говорит, что снова откройте STDOUT, это означает «создать новый экземпляр STDOUT». Этот новый экземпляр отличается от родительского.Это то, как вы можете иметь несколько терминалов, открытых в вашей системе, и не позволить всем STDOUT идти в одно и то же место.
Канальное решение соединит дочерний элемент с родительским через канал (например, | в оболочке), и вам нужно будет прочитать родительский элемент из канала и мультиплексировать сам вывод.Родитель будет отвечать за чтение из канала и за то, чтобы он не чередовал вывод из канала и вывод, предназначенный для STDOUT родителя одновременно.Есть пример и запись здесь каналов.
Фрагмент:
use IO::Handle;
pipe(PARENTREAD, PARENTWRITE);
pipe(CHILDREAD, CHILDWRITE);
PARENTWRITE->autoflush(1);
CHILDWRITE->autoflush(1);
if ($child = fork) { # Parent code
chomp($result = <PARENTREAD>);
print "Got a value of $result from child\n";
waitpid($child,0);
} else {
print PARENTWRITE "FROM CHILD\n";
exit;
}
Посмотрите, как дочерний элемент не пишет в стандартный вывод, а использует канал для отправкисообщение для родителя, который делает запись со своим stdout.Обязательно посмотрите, как я пропустил такие вещи, как закрытие ненужных файловых дескрипторов.