Основные вопросы о трубах - PullRequest
1 голос
/ 24 декабря 2009

У меня есть несколько основных вопросов о трубах, в которых я не уверен.

a) Каково стандартное поведение, если процесс записи в канал уничтожается (т. Е. SIGKILL SIGINT) Он закрывает канал? Это промывает трубу? Или поведение не определено?

б) Каково стандартное поведение, если процесс возвращается нормально? Гарантируется ли промывка трубы и ее закрытие? (конечно, без явного указания).

Мне бы хотелось, чтобы эти ответы были как можно более общими, но на самом деле, если это полностью зависит от спецификаций ОС, я могу принять это! Однако, если есть стандарт Posix или текущее определенное поведение Windows, я был бы очень рад узнать.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 24 декабря 2009

а. Каково стандартное поведение, если процесс записи в канал убивается (т. Е. SIGKILL SIGINT) Он закрывает канал? Это промывает трубу? Или поведение не определено?

SIGKILL никогда не разрешает какую-либо очистку - процесс умирает, мертвый. С SIGINT это зависит от того, обрабатывает ли процесс сигнал. Если это так, он может выйти через exit (2), который очищает стандартные дескрипторы файла ввода / вывода. Вопрос в том - был ли канал подключен к стандартному выходу или через popen ()? Если это так, ожидающие буферизованные данные могут быть сброшены; если нет, то буферизованные данные отсутствуют, поэтому очистка не имеет значения.

Если в канале есть непрочитанные данные, эти данные остаются в канале, готовые для чтения ридером, при условии, что ридер есть.

б. Каково стандартное поведение, если процесс возвращается нормально? Гарантируется ли промывка трубы и ее закрытие? (конечно, без явного указания).

Это зависит от того, был ли канал подключен через стандартный ввод / вывод или нет. Если нет, то ничего не ожидается. Если это так, то да, любой материал в буферах будет очищен при закрытии стандартного потока ввода / вывода.


с. Спасибо за информацию о сигналах и непрочитанных данных, но меня немного смущает стандартное соединение каналов ввода / вывода. После того, как вы упомянули popen (), я посмотрел его, и страница man говорит, что его возвращаемое значение идентично потоку ввода-вывода, и потоки по умолчанию полностью буферизуются. Я просто не понимаю разницу между этими двумя понятиями, и при этом я не понимаю, откуда взялась разница.

Основной системный вызов для создания каналов - pipe(2). Он создает два файловых дескриптора, один для конца чтения канала, другой для конца записи. Если вы больше ничего с ними не делаете, они остаются как файловые дескрипторы с небуферизованным выводом (через write (2) и связанные системные вызовы). Если процесс завершается, в приложении нет буферизации; труба закрыта.

Если вы используете popen(3), то это сделает для вас гораздо больше работы. Он по-прежнему вызывает pipe(2) для создания каналов, но затем выполняет fork(2). Дочерний организует правильную конфигурацию каналов и запускает дочерний процесс. Родитель также закрывает неиспользуемый конец канала и использует fdopen(3) для создания стандартного потока файлов ввода / вывода для использования вызывающим процессом.

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

1 голос
/ 24 декабря 2009

Обычное поведение состоит в том, что все файловые дескрипторы закрываются, когда процесс завершается. Это означает, что канал, как и любой другой дескриптор открытого файла, обычно закрывается.

Одна интересная вещь о каналах, однако: в POSIX, если процесс пишет в канал, который был закрыт, пишущий получит сигнал SIGPIPE. <Ч /> Изменить:

Предупреждение: Разница между sIG-завершением и обычным завершением заключается в том, что, как и при любой другой записи файла, вы можете потерять данные, которые были буферизованы (через запись FILE) и еще не записаны в дескриптор файла.

...