Помощь с асинхронным вводом / выводом - PullRequest
1 голос
/ 11 июля 2010

Я много занимался поиском и до сих пор не могу понять, как решить мою проблему.Я пишу программу с графическим интерфейсом (в WinAPI, поэтому не MFC, пожалуйста) для связи с другой программой (на основе командной строки).Я использую анонимные каналы, поскольку все локально (но, может быть, именованные каналы были бы лучше?), Которые затем я использую CreateProcess ();чтобы запустить программу, из которой я пытаюсь получить вывод.

Теперь я только что перешел с синхронного на асинхронный несколько часов назад и столкнулся с несколькими проблемами (хотя синхронный не сделал то, что я хотел в любом случае).Первая проблема заключается в том, что я все еще сталкиваюсь с той же проблемой, с которой столкнулся при выполнении синхронного ввода-вывода;если я запускаю функцию «чтение» (или «запись») более одного раза, программа зависнет.У меня не может быть этого, потому что цель программы состоит в том, чтобы периодически обновлять графический интерфейс пользователя, что является выводом командной строки.

Вторая проблема, и в конечном итоге более серьезная, - это новая проблема с моим асинхронным вводом-выводом;он не читает весь вывод, как мой синхронный.Он читает до тех пор, пока программа, из которой я читаю, не отправит возвращаемый символ (или это просто совпадение, что именно в этот момент происходит прекращение чтения).Я чувствую, что, возможно, я не до конца понимаю возможности OVERLAP, но я чувствую себя застрявшим, читая так много MSDN прямо сейчас, поэтому, возможно, я упускаю из виду некоторые его важные аспекты.

Такв основном, приведенный ниже код - это минимум того, что я делаю.Я попытался использовать различные методы цикла for () и while (), чтобы попытаться пройти через все выходные данные, но, похоже, ничего не получится.Обратите внимание, что BUFSIZE определен в 0x1000, что на самом деле больше, чем небольшая тестовая программа, которую я написал для этой потребности.

    ::ReadFile(_hChild_Out_Rd, chBuf, BUFSIZE, &dwRead, &o1);
chBuf[dwRead] = '\0';
::SetDlgItemTextA(global,IDO_WORLDOUT,chBuf);

Так есть ли у кого-нибудь какие-нибудь идеи?

Большое спасибо заВаша помощь!

С уважением,Деннис М.

Ответы [ 2 ]

2 голосов
/ 11 июля 2010

Это похоже на синхронный код.При асинхронном (OVERLAPPED) вводе / выводе вы не можете использовать буфер до завершения операции.Установите hEvent член структуры OVERLAPPED и измените основной цикл с PeekMessage на MsgWaitForMultipleObjects, чтобы ваша программа могла реагировать на события ввода / вывода.Затем вы можете подождать как с дескриптором операции OVERLAPPED, так и с дескриптором процесса, чтобы вы знали, когда вышла другая программа.

0 голосов
/ 11 июля 2010

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

Вы создаете файл с отображением в памяти следующим образом:

SECURITY_ATTRIBUTES sa;
sa.bInheritHandle = TRUE;
sa.nLength = sizeof( sa );
sa.lpSecurityDescriptor = NULL;

hdFile = CreateFileMapping(INVALID_HANDLE_VALUE,&sa,
   PAGE_READWRITE,0,dwBufSize, L"SomeName");

Затем вы получаете указатель на разделяемую память, как этот

pOutSharedMemory=MapViewOfFile(hdFile,FILE_MAP_ALL_ACCESS,0,0,dwBufSize);

, теперь вы можете сопоставить указатели с памятью

например, пару счетчиков, чтобы отслеживать, где вы находитесь в памяти(в пределах dwBufSize)

pdwReadOffset = reinterpret_cast<DWORD*>(pOutSharedMemory)
pdwWriteOffset = pdwReadOffset + sizeof(DWORD)

затем есть некоторая структура, которую вы затем читаете / записываете в память, используя memmove

, вам придется позаботиться о синхронизации на месте, используя критические секции и т. д.

...