|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Ноя 3, 2004 00:51:46 · Поправил: Fess exe Есть дочерний консольный процесс. Мой процесс пишет в его input handle и читает из его output handle и handle вывода ошибок через анонимные пйпы. При чтении таким образом DWORD written; while(true) { written=0; RtlZeroMemory(ReadBuf,4048); // ReadBuf - массив из 4048 байтов if((!ReadFile(hRead,ReadBuf,4048,&written,NULL))) { errmsg(); return; } if(!written) { return; } if(!ReadBuf[0]) { return; } else { /* Чтение из буфера */ } } программа виснет, вероятнее всего потому, что ReadFile натыкается на то, что консоль ждёт ввода, после чего останавливается. Как сделать так, чтоб программа не висла, а останавливалвсь? То есть как узнать завершил ли дочерний прцесс обработку введённого или нет? |
|
|
Дата: Ноя 3, 2004 16:20:13 Fess exe Дочерний процесс твой или любой? |
|
|
Дата: Ноя 3, 2004 19:24:41 Твоя программа ждет пока дочерний процесс выведет 4048 байт. В MSDN все описано и есть пример, как работать с анонимными каналами(pipes). То есть как узнать завершил ли дочерний прцесс обработку введённого или нет? Такого сделать нельзя. Но можно узнать сколько на данной момент байт было выведено на паток. PeekNamedPipe(hRead,nul, 0, &bread, &avail, nul); if (avail>0) { Читаем данные } В avail лижит число байт выведенных на поток. Проверяй на закрытие потока. exit=0; GetExitCodeProcess(pin.hProcess,exit); if (exit <> STILL_ACTIVE) { выходим из вечного цыкла } |
|
|
Дата: Ноя 9, 2004 00:45:24 q_q Процесс дочерний мой. Pavia То есть только с именованными пайпами или эта функция(PeekNamedPipe) и для анонимных работает? |
|
|
Дата: Ноя 9, 2004 12:14:44 Правка Fess exe Читаем описание функции. |
|
|
Дата: Ноя 10, 2004 00:59:30 Ага, прочёл, каюсь. Но вроде бы оно не до конца решает проблему ибо придётся ждать какое-то фиксированное время после того,как avail станет 0, а потом не обращать внимание на попытки дочернего процесса вывести ещё чего-н. Или я опять что-то пропустил? |
|
|
Дата: Ноя 10, 2004 02:43:18 · Поправил: IceStudent Правка ибо придётся ждать какое-то фиксированное время после того,как avail станет 0 Что-то я не понял. avail станет равным 0 после вызова ReadFile, которая и опустошит буфер трубы (pipe). Как сделать так, чтоб программа не висла, а останавливалвсь?. Используем ReadFile с заполненной структурой OVERLAPPED. В этом случае поток останавливается до тех пор, пока в трубе (pipe) не появятся данные. Этот момент сигнализируется двумя событиями: возвращается управление из ReadFile и сигнализируется событие (hEvent) в OVERLAPPED. Но нет гарантии, что консольная программа что-то выдаст и поток проснётся. Чтобы избежать этого, с PeekNamedPipe можно сделать так:
// 1) посылаем данные в консоль.
// нужно точно узнать, что именно ожидает консольная программа:
// - некий завершающий символ (';','\r\n','\n'...)
// - нажатие какой-то клавишы (редко, на бывает)
bResult = WriteFile(hWrite,lpBuf,dwBuf,lpWritten,NULL);
nAvail = 0;
// пока не появятся данные в трубе
while(!nAvail){
// делаем что-то полезное (следим за временем), просто спим
Sleep(200);
// проверяем наличие данных в трубе
bResult = PeekNamedPipe(hRead,NULL, 0, &nRead, &nAvail, NULL);
}
// на то случай, если вышли из цикла по своей надобности
if (nAvail){
// здесь читается буфер фиксированного размера
// можно также читать сразу весь буфер трубы:
// ReadFile(hRead,lpBuf,nAvail,&nRead,NULL);
Result = ReadFile(hRead,lpBuf,dwBuf,&nRead,NULL);
}
То есть как узнать завершил ли дочерний прцесс обработку введённого или нет? Это зависит от самого процесса — как именно он завершает обработку введённого: начинает выводить результат сразу весь или потихоньку по чуть-чуть (например, показывая текущее состояние обработки). Средствами системы это не проверить, здесь нужно самому просматривать полученные данные на завершающий флаг (специальный символ/строку/символы переноса строки), проверять, не остались ли ещё невыбранные данные, если наш буфер оказался мал. Но все эти условия зависят от самого консольного приложения… |
|
|
Дата: Ноя 12, 2004 23:58:56 Привидённый выше пример кода меня несколько смущает, ибо прграмма так тоже зависнет, если консоль остановиться и будет ждать ввода. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.063 |