Windows: дочерний процесс с перенаправленным вводом и выводом - PullRequest
4 голосов
/ 16 сентября 2010

Я пытаюсь создать дочерний процесс с перенаправленным вводом и выводом (как описано здесь - http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx).

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

В этом коде, однако, программазакрывая каналы после чтения и записи (в WriteToPipe и ReadFromPipe), так что фактически программа просто читает файл, выгружает его в поток ввода дочернего процесса и затем читает ответ дочернего процесса.

Теперь, чтоm ищет код, в котором мы не будем закрывать каналы, но мы будем постоянно публиковать запросы и читать ответ дочернего процесса (в отличие от выполнения всего 1 запроса).

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

Обновление:

Может кто-нибудь хотя бы сказать мне, является ли использование класса .NET Process с RedirectStandardInput и RedirectStandardOutput хорошим вариантом?

Ответы [ 2 ]

1 голос
/ 19 апреля 2011

Была точно такая же проблема, и была решена с помощью PeekNamedPipe (что в соответствии с MSDN также подходит для анонимных каналов чтения) для проверки доступных данных перед каждым вызовом ReadFile.Это устранило проблемы с блокировкой, которые я получал, и позволило моим GetExitCodeProcess() увидеть, что процесс завершился, и очистить каналы.

0 голосов
/ 14 декабря 2010

Да - класс .Net Process перенаправляет стандартный ввод / вывод дочернего процесса с анонимными каналами очень похоже на связанный образец, если вы используете RedirectStandardInput и RedirectStandardOutput, так что это, вероятно, довольно хорошо опция.

Что касается того, почему ReadFile зависает - похоже, что эта функция ожидает, пока дочерний процесс не отправит какие-либо данные назад или не закроет канал. Если вы хотите непрерывно публиковать запросы в дочернем процессе, вам необходимо:

  • Точно знаю, когда уместно прочитать , чтобы вы не оставались в ожидании / блокировке для дочернего процесса (например, вы читаете только сразу после отправки запроса). Эта стратегия очень рискованна, поскольку всегда существует вероятность того, что дочерний процесс не будет работать так, как ожидалось, и вы будете ждать дочернего процесса бесконечно долго.

  • Иметь специальный поток для чтения - если у вас есть специальный поток для чтения, то не имеет значения, что поток может бесконечно ждать дочерний процесс, так как другие ваши потоки все еще могут отправлять запросы и работать в обычном режиме. Этот метод более сложный, чем первый, однако, если все сделано правильно, он гораздо надежнее. Единственным другим недостатком этого подхода является то, что он требует наличия дополнительной цепочки чтения для каждого дочернего процесса, а это означает, что он не очень хорошо масштабируется, если вам необходимо взаимодействовать с большим количеством дочерних процессов.

  • Использовать асинхронный ввод-вывод - Функцию ReadFile можно вызывать так, чтобы она всегда сразу возвращалась, однако уведомляет вас о завершении чтения (I Я немного размыт о точных деталях того, как это работает, так как я больше привык к C #). Это известно как Асинхронный ввод-вывод и является наиболее универсальным из этих трех методов, поскольку позволяет взаимодействовать со многими дочерними процессами без необходимости выделенного потока для каждого из них. Компромисс, однако, заключается в том, что это также наиболее сложно сделать правильно (по крайней мере, на мой взгляд).

...