Есть ли у stdin и stdout какие-либо ресурсы?

Стандартный ввод и стандартный вывод независимы или нет?

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

        stdin       <- stdout
parent                        child
stdout ->      stdin

Если дочерний элемент (асинхронно) непрерывно считывал данные из своего стандартного ввода и записывал данные в свой стандартный вывод, но родитель просто записывал в стандартный ввод дочернего элемента и вообще не читал из стандартного вывода дочернего элемента:

        stdin|     << stdout
parent                       child
stdout ==>==> stdin

будет ли в конечном итоге блокировка? Разделяют ли стандартный ввод и стандартный вывод какой-либо буфер? В частности, через C ++ std::cin (istream) и std::cout (ostream), если это необходимо, чтобы ответить. Требует ли стандарт, чтобы они делали или не разделяли такую ​​вещь, или он оставляет это на усмотрение реализации?

Что случилось бы?

1

Решение

Вы не можете «прикрепить» файловый дескриптор процесса к файловому дескриптору другого процесса. Что вы делаете (если ваша операционная система поддерживает это) — это назначаете два файловых дескриптора на концах «канала». Каналы нигде не указаны в стандарте C / C ++ (они определены в POSIX), и вы не найдете никакой стандартной библиотечной функции C / C ++, которая вообще на них ссылается.

Как реализовано в Unix (и Unix-подобных) системах, канал — это немного больше, чем буфер где-то в операционной системе. Пока буфер не заполнен, процесс может записывать данные на входной конец канала; данные просто добавляются в буфер. Пока буфер не пуст, процесс может считывать данные из выходного конца буфера; данные удаляются из буфера и передаются процессу чтения. Если процесс пытается записать в канал, чей буфер заполнен, или прочитать из канала, чей буфер пуст, процесс «блокируется»: то есть он помечается планировщиком ядра как неработоспособный и остается в этом состоянии до труба может обработать его запрос.

Сценарий, описанный в вопросе, должен включать две трубы. Один канал используется для того, чтобы позволить stdout родителя отправлять данные в дочерний stdin, а другой — для того, чтобы позволить stdout дочернего объекта отправлять данные в stdin родителя. Эти две трубы полностью независимы друг от друга.

Теперь, если родительский элемент прекращает чтение из своего стандартного ввода, но дочерний процесс продолжает запись в свой стандартный вывод, тогда в конечном итоге буферный канал заполнится. (На самом деле это не займет очень много времени. Буферы канала не очень велики, и они не растут.) В этот момент дочерний блок блокирует попытки записи в канал. Если ребенок не многопоточный, то когда он блокируется, то все. Он перестает работать, поэтому он больше не читает с его стандартного ввода. И если дочерний элемент прекращает чтение из своего стандартного ввода, тогда другой канал скоро заполнится, и родительский блок также заблокирует попытку записи в стандартный вывод.

Таким образом, нет необходимости в совместном использовании ресурсов для достижения тупика.

Это очень известная ошибка в процессах, которые порождают ребенка и пытаются передать данные ребенку во время чтения ответа ребенка. Если читатель не поспевает за полученными данными, вероятна тупиковая ситуация. Вы найдете много информации об этом, выполнив поиск, например, «тупиковая ситуация с буфером буфера». Вот несколько примеров ссылок, просто наугад:

Рэймонд Чен, на MSDN: http://blogs.msdn.com/b/oldnewthing/archive/2011/07/07/10183884.aspx

Прямо здесь, в StackOverflow (со ссылкой на Python, но проблема идентична): Может кто-нибудь объяснить тупик буфера трубы?

Дэвид Глассер, с 2006 года: http://web.mit.edu/6.033/2006/wwwdocs/writing-samples/unix-DavidGlasser.html («Эти ограничения не просто теоретические — их можно увидеть на практике из-за того, что ни одна из основных форм межпроцессного взаимодействия, позже разработанная в Unix, не наложена поверх трубы».)

7

Другие решения


По вопросам рекламы [email protected]