Возможно ли, что close (0) выполняется до dup (pfds [1])? Если да, , тогда в этом случае программа не будет вести себя так, как ожидалось.
Да, это возможно, чтобы иметь родителя успешно завершить close(0)
перед ребенком вызывает dup(pfds[1])
. Однако это не проблема. Когда вы переделываете новый процесс, новый процесс получает всю копию адресного пространства памяти родителя, включая дескрипторы открытых файлов (кроме тех, которые отмечены флагом O_CLOEXEC
- см. fcntl(2)
). Таким образом, по существу, каждый процесс имеет свою личную копию дескрипторов файлов и изолирован и свободен делать все, что захочет, с этой копией.
Таким образом, когда родительский звонит close(0)
, он закрывает только свою копию дескриптора файла 0 (stdin
); он никак не влияет на ребенка, который все еще имеет ссылку на stdin
и может использовать его при необходимости (хотя в этом примере он не будет).
Что является использование следующих строк кода:
close(pfds[0]); /* we don't need this */
close(pfds[1]); /* we don't need this */
Лучшие практики мандат, который вы должны закрыть дескрипторы файлов, которые вы не используете - это дело для close(pfds[0])
. Неиспользуемые дескрипторы открытых файлов потребляют пространство и ресурсы, поэтому держите его открытым, если вы не собираетесь его использовать?
close(pfds[1])
является немного более тонким, хотя. Трубы сообщают о завершении файла только в том случае, когда в буфере труб больше нет данных и нет активных авторов, то есть нет живых процессов, у которых труба открыта для записи.Если вы не закроете pfds[1]
в родительском, программа будет висеть вечно, потому что wc(1)
никогда не увидит конца ввода, так как есть процесс (wc(1)
), который имеет трубу, открытую для записи, и как таковой может (но не будет) напишите больше данных.
Tl; DR: close(pfds[0])
- это просто хорошая практика, но не обязательная; close(pfds[1])
абсолютно необходим для обеспечения правильности программы.
Как ребенок все еще будет открывать fd 0? файловый дескриптор, совместно используемый в процессе, и dup() принимают самый низкий доступный FD. Я не могу понять. –
fd 0 делится через вызов fork(). Но после этого каждый процесс имеет свою собственную память и ресурсы. Таким образом, родительский элемент может закрыть fd 0, а затем он может использоваться для вызова dup(). Это ничего не делает для fd 0 у ребенка, который все еще указывает на stdin. –
Вопрос 2 на самом деле не о хороших практиках ведения бухгалтерского учета, есть намного больше, чем это. Попробуйте удалить 'close (pfds [1])', и вы останетесь с висячей программой. [Подсказка: трубы не сообщают EOF, когда есть хотя бы писатель] –