Подтвердить что ты не робот

Почему вы должны закрыть трубку в Linux?

При использовании трубы для связи процесса и процесса, какова цель закрытия одного конца трубы?

Например: Как отправить простую строку между двумя программами с помощью труб?

Обратите внимание, что одна сторона канала закрыта в дочернем и родительском процессах. Почему это необходимо?

4b9b3361

Ответ 1

Если вы подключаете два процесса - родительский и дочерний - используя канал, вы создаете канал перед вилкой.

Вилка позволяет обоим процессам иметь доступ к обоим концам трубы. Это нежелательно.

Предполагается, что читающая сторона узнает, что автор закончил, если он замечает условие EOF. Это может произойти только в том случае, если все стороны письма закрыты. Поэтому лучше всего закрыть его запись FD ASAP.

Писатель должен закрыть свой считывающий FD только для того, чтобы не открывать слишком много FD и, таким образом, достигать, возможно, существующего предела открытых FD. Кроме того, если только тогда умирает только тогда, писатель получает уведомление об этом, получая SIGPIPE или хотя бы ошибку EPIPE (в зависимости от того, как определяются сигналы). Если есть несколько читателей, писатель не может обнаружить, что "реальный" ушел, продолжает писать и застревает, поскольку записывающий FD блокирует в надежде, "неиспользуемый" читатель что-то прочитает.

Итак, здесь подробно, что происходит:

  • родительский процесс вызывает pipe() и получает 2 дескриптора файла: позвоните ему rd и wr.
  • вызов родительского процесса fork(). Теперь оба процесса имеют rd и a wr.
  • Предположим, что дочерний процесс должен быть читателем.

    Тогда

    • родитель должен закрыть свой конец для чтения (для того, чтобы не растрачивать FD и для правильного обнаружения умирающего читателя) и
    • ребенок должен закрыть свой конец записи (чтобы можно было обнаружить условие EOF).

Ответ 2

Количество дескрипторов файлов, которые могут быть открыты в данный момент времени, ограничено. Если вы продолжаете открывать трубы и не закрываете их довольно скоро, у вас закончится FD и больше не сможет открыть ничего: не трубы, а не файлы, а не сокеты,...

Еще одна причина, по которой важно закрыть трубу, - это когда закрытие имеет смысл для приложения. Например, обычное использование труб - отправить errno из дочернего процесса родительскому при использовании fork и exec в запустить внешний программы:

  • Родитель создает канал, вызывает fork, чтобы создать дочерний процесс, закрывает конец записи и пытается прочитать из канала.
  • Детский процесс пытается использовать exec для запуска другой программы:
    • Если exec терпит неудачу, например, потому что программа не существует, ребенок записывает errno в канал, а родитель читает ее и знает, что пошло не так, и может сказать пользователю.
    • Если exec успешно, труба закрывается без записи. Функция read в родительском возвращает 0, указывающая, что канал закрыт и знает, что программа была успешно запущена.

Если родительский элемент не закрыл свой конец записи, прежде чем пытаться читать из этого канала, это не сработает, потому что функция read никогда не вернется, когда exec будет успешным.