Есть ли размер буфера, прикрепленный к stdout? - PullRequest
11 голосов
/ 14 января 2010

Я пытаюсь найти некоторую информацию об ограничениях данных, связанных с stdout в Windows. Я не могу найти информацию на MSDN.

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

  2. Если stdout перенаправлен (например, путем запуска процесса из .Net и использования свойства ProcessStartInfo.RedirectStandardOutput), это как-то влияет на объем записываемых данных? Когда я читаю из потока stdout в вызывающем процессе, это влияет на ограничения?

  3. Связаны ли эти ограничения каким-либо образом с именованными каналами?

Ответы [ 3 ]

19 голосов
/ 14 января 2010

Это зависит от того, куда он идет - но да, если вы перенаправите вывод в .NET, вы можете легко столкнуться с проблемами, если вы не прочитаете вывод. Когда буфер заканчивается, запись в стандартный вывод дочернего процесса блокируется. Одной из распространенных причин взаимоблокировки является «родительский» процесс, ожидающий выхода «потомка» и затем считывающий выходные данные - это не сработает, если дочернему элементу требуется, чтобы родитель прочитал выходные данные, чтобы освободить буферное пространство. 1001 *

.NET несколько упростил эту задачу, позволив подход, основанный на событиях, с Process.OutputDataReceived и Process.ErrorDataReceived. Это означает, что вам не нужно запускать два потока (один для чтения stdout, другой для чтения stderr) только для предотвращения блокировки процесса ...

4 голосов
/ 14 января 2010

Некоторые вещи, которые нужно иметь в виду:

1) Джон прав: если лимит буфера достигнут, вызов записи в вашем подпроцессе будет заблокирован. Вам нужно слить поток stdout, если он не перенаправлен куда-либо, что приведет к его автоматическому сбою - как файл. Трубы необходимо слить, и, как правило, если вы можете «прикрепить» к выходу подпроцесса, вы присоединяете к трубе.

2) I / O для выходного потока буферизуется , вероятно , что означает, что если подпроцесс записывает некоторую информацию в стандартный вывод без явного вызова flush(), что почти всегда так, вы можете не вижу выхода. Flush вызывается автоматически при выходе из процесса, поэтому, если это небольшой небольшой подпроцесс, у вас должно быть все в порядке, но если это не так, у вас нет реального способа заставить его вывод отображаться, когда вы этого хотите.

3) Именованные каналы - это, по сути, буфер, поддерживаемый ОС, который можно записывать и читать из него, то есть они похожи на файл, в который вы можете записывать из одного процесса и читать из другого, фактически не имея накладные расходы на наличие файла на диске. Очень удобно для связи между процессами, но все ограничения ввода-вывода с буферизацией / полными буферами все еще применяются.

3 голосов
/ 21 декабря 2010

стандартный вывод имеет буфер 1024 байта

...