Вопрос

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

а) Каково стандартное поведение, если процесс, записывающий в канал, прерывается (т.е.SIGKILL SIGINT) Закрывает ли это канал?Промывает ли это трубу?Или поведение не определено?

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

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

Спасибо.

Это было полезно?

Решение

a.Каково стандартное поведение, если процесс, записывающий в канал, прерывается (т.е.SIGKILL SIGINT) Закрывает ли это канал?Промывает ли это трубу?Или поведение не определено?

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

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

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

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


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

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

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

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

Другие советы

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

Однако есть одна интересная вещь о трубах:в POSIX, если процесс выполняет запись в канал, который был закрыт, записывающее устройство получит сигнал SIGPIPE.


Редактировать:

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top