Почему я не могу дублировать 2 (p [1], 1), а затем записать (1, буфер, 1)?
Можно, хотя это кажется бессмысленным. Однако было бы более разумно, если бы вы пытались использовать одну из функций ввода-вывода, которая записывает (только) в стандартный вывод.
Это работает, только если я пишу (p [1], buffer, 1) без dup2 (p [1], 1).
Это зависит от того, что вы подразумеваете под «делами». Когда я запускаю ваш исходный код, программа никогда не печатает никаких выходных данных и никогда не завершается, но это не означает, что записи родителя не успешно отправили данные дочернему элементу.
Проблема в том, что ребенок не знает, когда достигнут конец ввода. Он ожидает сигнала конца файла на своем входе, который не будет поступать, пока есть любые дескрипторы открытого файла, связанные с концом записи канала.
Если родительский объект не дублирует конец записи канала, то у него открыт только один дескриптор файла, а у дочернего - один. Оба закрывают свои в подходящее время. Но в представленном вами коде родительский элемент помещает p[1]
в файловый дескриптор 1, так что он имеет два открытых файловых дескриптора, относящихся к концу канала. Он закрывается только p[1]
, оставляя файловый дескриптор 1 открытым, поэтому ребенок продолжает ждать ввода.
Родитель закроет FD 1, если он выйдет, что позволит ребенку закончить, но ожидает, чтобы ребенок завершил сначала. Это одна из наиболее распространенных ошибок взаимоблокировок, связанных с перенаправлением ввода-вывода. Я бы предложил просто не иметь родительского дублирования файлового дескриптора, так как дублирование на FD 1 излишне мешает ему использовать стандартный вывод для каких-либо других целей. Но если он не работает, он должен закрыть оба файловых дескриптора, прежде чем дочерний процесс завершится.