silentspring 发表于 2009-12-28 20:31:56

想在父进程中监视子进程是否向自己发送了数据

我想在父进程中派生出一个子进程,让两者之间用匿名管道通信,然后在父进程中监视子进程是否通过fprintf和fflush向自己发送了数据。

父进程代码如下(代码中使用了ACE):
#include "stdafx.h"
#include<iostream>
#include<ace/ACE.h>
#include<ace/OS.h>
#include<ace/SStringfwd.h>
#include<ace/SString.h>
#include<ace/Event.h>
#include<ace/Thread_Manager.h>
#include<ace/Process.h>
using namespace std;

#define READ 0
#define WRITE 1

int _tmain(int argc, _TCHAR* argv[])
{
   //创建管道
   ACE_HANDLE parent2child;
   ACE_HANDLE child2parent;

   if ( ACE_OS::pipe(parent2child) == -1 ||ACE_OS::pipe(child2parent) == -1 )
   {
         return -1;
   }

   ACE_Process_Options opt(1); // inherit env   

   // set one end of pipe as stdin/stdout in child process
   opt.set_handles(parent2child, child2parent );

   // handle duplicated so close it here
   ACE_OS::close(parent2child);
   ACE_OS::close(child2parent);

    std::string m_startupCmd ="D:\\ChildProcess.exe";
   opt.command_line(m_startupCmd.c_str());

   opt.creation_flags(DETACHED_PROCESS);
   opt.creation_flags(CREATE_NO_WINDOW);

   //派生子进程
   ACE_Process m_process;
   if( m_process.spawn(opt) == -1 )
   {
         ACE_OS::close(child2parent);
         ACE_OS::close(parent2child);
         return -1;
   }
   m_process.close_dup_handles();
   m_process.close_passed_handles();

   // close server side for handles as it should be in child by now
   opt.release_handles();

   // put FILE stream around the pipe
   FILE*       m_pread; // FILE stream from child process
   FILE*       m_pwrite; // FILE stream to child process
   m_pread = ACE_OS::fdopen(child2parent,"r");
   m_pwrite = ACE_OS::fdopen(parent2child,"a");

   if( m_pread == 0 || m_pwrite == 0 )
   {
         return -1;
   }
      
   //监视管道中是否有从子进程中发送的数据
   //Option1: WaitForSingleObject
   //监视管道5秒钟
   int retVal = WaitForSingleObject(child2parent, 5*1000);
   cout< < "WaitForSingleObject retVal:<"< < retVal< < ">."< < endl;
   cout< < "GetLastError:<"< < GetLastError()< < ">."< < endl;

   return 0;
}

子进程代码如下:
int main(int argc, char* argv[])
{
   fprintf(stdout, "0 1.0.0.0\n");
   fflush(stdout);
   ......
   ......
   return 0;
}

现在的问题是:
即使子进程不向父进程发送数据(例如在子进程开始处就Sleep 1000 秒),父进程的WaitForSingleObject也会立刻返回,且返回值为0, GetLastError()也返回0。
如果将“Option1”换作如下采用select的“Option2”,select返回值为-1,WSAGetLastError()返回10038(Socket operation on nonsocket)。
   //Option2: select on child2parent
   fd_set fds;
   struct timeval tv;
   FD_ZERO(&fds);
   FD_SET((int)child2parent, &fds);
   tv.tv_sec = 5;
   tv.tv_usec = 0;
   int retVal = select((int)child2parent+1, &fds, NULL, NULL, &tv);
   cout< < "select retVal:<"< < retVal< < ">."< < endl;
   cout< < "WSAGetLastError:<"< < WSAGetLastError()< < ">."< < endl;

我想请教大家,如何才能真正实现在父进程中监视子进程是否向管道中真正发送了数据?是不是除了WaitForSingleObject和select之外还有别的API可用?还是我错误地使用了这两个API?

谢谢大家!!!

[ 本帖最后由 silentspring 于 2009-12-29 05:51 编辑 ]

silentspring 发表于 2009-12-29 05:51:41

回复 #1 silentspring 的帖子

没有人知道吗?:(
页: [1]
查看完整版本: 想在父进程中监视子进程是否向自己发送了数据