2010-07-11 73 views
1

我一直在做大量的搜索,仍然似乎无法弄清楚如何解决我的问题。我正在编写一个GUI程序(在WinAPI中,所以不需要MFC)与另一个程序(基于命令行)进行通信。我使用匿名管道,因为一切都是本地的(但也许命名管道会更好?),然后我使用CreateProcess();运行我试图从中获取输出的程序。帮助异步I/O

现在,我刚刚从几小时前的同步转移到异步,并且遇到了一些问题(即使同步没有做我想要的东西)。第一个问题是我在运行同步I/O时仍遇到同样的问题;如果我运行我的“读取”(或“写入”)功能不止一次,程序将冻结。我不能这样做,因为程序的目的是定期更新GUI到命令提示符的输出。

第二个问题,最终更严重的是一个新的异步I/O;它不像我的同步一样读取整个输出。它读取,直到我正在阅读的程序发送返回字符(否则,它恰好是巧合,这是它停止阅读的点)。我觉得我可能不完全理解OVERLAP的功能,但是现在我正在阅读如此多的MSDN,因此我可能忽略了一些重要的方面。

所以基本上,下面的代码是我正在做的最低限度。我曾尝试使用各种for()和while()循环技术来尝试获取所有输出数据,但它似乎是不行的。请注意,BUFSIZE定义在0x1000,这实际上比我为这个需求编写的小测试程序还要多。

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

那么,有没有人有任何想法?

非常感谢您的帮助!

问候,
丹尼斯M.

回答

2

这看起来像同步代码。使用异步(OVERLAPPED)I/O时,只有操作完成后才能使用缓冲区。设置OVERLAPPED结构的hEvent成员,并将主循环从PeekMessage更改为MsgWaitForMultipleObjects,以便您的程序可以响应I/O事件。然后,您可以等待OVERLAPPED操作手柄以及进程句柄,以便知道何时退出其他程序。

+0

我现在唯一的问题是如何将流程写入命名管道?我创建了一个名称管道,并尝试以与匿名管道相同的方式运行一个进程,但无法访问输出。有任何想法吗? – RageD 2010-07-11 06:16:00

+0

匿名教皇应该为此目的而工作得很好,但是如果您想使用命名管道,请注意您必须单独打开两端(并且两端都是双向的),不像匿名情况下您得到一对手柄通过单个API调用到单向管道的末端。 – 2010-07-11 11:56:31

+0

执行'CreatePipe()'返回的文件句柄,甚至是否设置了'FILE_FLAG_OVERLAPPED'? 'CreatePipe()'没有“文件模式”或“打开模式”参数。 – bk1e 2010-07-11 16:28:52

0

您可能希望查看内存映射文件,您可以在内存中构建一个队列,并从一个地方写入并从另一个地方读取。在一个项目中,我做了一个循环队列,其中一个进程写入队列,另一个进程在有时间的时候读取。

您可以创建一个内存映射文件是这样的:

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

读/写的内存,你必须照顾使用关键部分的同步等。

+0

你真的需要使用管道,我不知道有什么方法将'STARTUPINFO'的'hStdOutput'成员设置为内存映射区域,子进程也不知道如何将访问同步到循环缓冲区。 http://msdn.microsoft.com/en-us/library/ms686331(v=VS.85).aspx – 2010-07-11 01:35:39

+0

由于有不同的读写计数器和互斥量应该足以同步它们,但我同意命名管道可能是OPs情况最好的,只是提出了几年前我已经使用的替代方案。 – 2010-07-11 02:06:51