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

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

4 голоса | спросил Oleg Zhylin 15 +04002009-10-15T02:46:56+04:00312009bEurope/MoscowThu, 15 Oct 2009 02:46:56 +0400 2009, 02:46:56

1 ответ


0

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

  

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

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

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

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

ответил Tim Sylvester 15 +04002009-10-15T02:58:33+04:00312009bEurope/MoscowThu, 15 Oct 2009 02:58:33 +0400 2009, 02:58:33

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132