Небуферизованный CreateNamedPipe для использования в качестве стандартного вывода для CreateProcess.

StackOverflow https://stackoverflow.com/questions/1569425

Вопрос

Я хотел бы запустить произвольное приложение командной строки и прочитать его стандартный вывод по мере его создания.я использую CreateNamedPipe создать трубу, а затем поставить другой конец (открыть использованный CreateFile) к CreateProcess.При условии, что целевой процесс явно не манипулирует стандартной буферизацией вывода, есть ли способ убедиться, что рассматриваемый канал не буферизован или, по крайней мере, что в качестве размера буфера используется системный минимум?

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

Решение

Вы не можете контролировать размеры буфера.Вы можете передавать размеры буфера чтения и записи от 1 до CreateNamedPipe, но ядро ​​автоматически увеличит размеры этого буфера.По сути, размер буфера всегда будет не меньше самого большого объема данных, который был готов к чтению в любой момент времени.Другими словами, чем быстрее вы реагируете на доступные данные и чем меньше блоков данных, записываемых в канал, тем меньше останется буфер.

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

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

Имейте в виду, что при подключении канала к консольному приложению stdout, вывод обычно буферизуется этим приложением до это записано в трубу.Если вам нужен небуферизованный вывод, вам нужно будет использовать stderr.

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

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