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

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

1 ответ

Решение

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

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

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

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

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

Другие вопросы по тегам