利用匿名管道在父子进程间传递数据
进程间传递数据有很多种方法,常用到的有命令行、共享内存、内存映射文件、剪贴板、windows消息、socket等。
命令行的缺点是数据长度限制。Windows2000只能传递256个字节,内存映射文件、共享内存都需要一些进程同步才能很好的配合读写数据,剪贴板可能会被其他进程擦数数据。当多开的时候很难控制进程间的对应关系。
一种解决方案是生成随机命名的同步控制对象,然后利用命令行传递名字。同步控制对象可以通过唯一的名字再另一个进程中获取其引用。
相对来说用同步对象会稍有些麻烦,匿名管道可以很好的解决这些问题。子进程可以继承父进程中创建的句柄,父子进程一一对应的关系不会被打乱。而且使用简单,父子进程可以双向通信。
用法:
1. 首先创建两条匿名管道,一条用于发送数据给子进程,一条用于从子进程接收数据,安全描述符中指定可继承性 saAttr.bInheritHandle = TRUE;
2. 每条匿名管道包括两个句柄,一个读一个写,可以理解为管道的两端,从写端写出的数据可以从读端读取。所以父进程需要一条管道来接收数据,一条发送数据。
3. windows的IO操作都可以用WriteFile 和ReadFile来完成,默认模式下数据发送和接收是阻塞的,管道的数据发送与接收也可以用重叠模式来进行。
4. CreateProcess子进程时参数.bInheritHandle需要传真,保证句柄的可继承性。
5. 利用STARTUPINFO传递管道端口给子进程,父窗口发送数据的管道的读端口,和父窗口等待接收数据的管道的写端口,利用STDHANDLES来传递。
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
STARTUPINFO starinfo =
{0};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
starinfo.cb = sizeof(starinfo);
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
starinfo.hStdInput = hSendReadPipe;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
starinfo.hStdOutput= hRecvWritePipe;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
starinfo.hStdError = hRecvWritePipe;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
starinfo.dwFlags |= STARTF_USESTDHANDLES;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
6. 子进程从STDHANDLES获得两个句柄用来读写。
HANDLE hRead = GetStdHandle(STD_INPUT_HANDLE);
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
HANDLE hWrite = GetStdHandle(STD_OUTPUT_HANDLE);
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
下面是完整代码:
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
BOOL CreatePipe()
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
SECURITY_ATTRIBUTES saAttr;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
saAttr.bInheritHandle = TRUE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
saAttr.lpSecurityDescriptor = NULL;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*'创建匿名管道*/
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if (!CreatePipe(&hSendReadPipe,&hSendWritePipe, &saAttr, 0))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
::LogMsg("CreatePipe failed!");
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return FALSE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*'构造写句柄的复制体*/
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if(!DuplicateHandle(GetCurrentProcess(), hSendWritePipe,
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
GetCurrentProcess(), &hSendWritePipeDup, 0,FALSE,DUPLICATE_SAME_ACCESS))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
::LogMsg("DuplicateHandle Handle!");
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return FALSE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
CloseHandle(hSendWritePipe);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
//////////////////////////////////////////////////////////////////////////
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if (!CreatePipe(&hRecvReadPipe,&hRecvWritePipe, &saAttr, 0))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
::LogMsg("CreatePipe failed!");
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return FALSE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*'构造写句柄的复制体*/
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if(!DuplicateHandle(GetCurrentProcess(), hRecvReadPipe,
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
GetCurrentProcess(), &hRecvReadPipeDup, 0,FALSE,DUPLICATE_SAME_ACCESS))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
::LogMsg("DuplicateHandle Handle!");
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return FALSE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
CloseHandle(hRecvReadPipe);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return TRUE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
BOOL ReadFromPipe()
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
DWORD dwReaded =0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
char szBuf[255];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return ReadFile(hRecvReadPipeDup, szBuf, sizeof(szBuf), &dwReaded, NULL); ;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
void WaitForReply()
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while ( !ReadFromPipe())
{};
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
BOOL WriteToPipe()
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
char szData[1024];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
int nSize = sizeof(g_cmdData);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
CompressData((char*)&g_cmdData,nSize,szData);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*'对管道进行写操作*/
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
DWORD dwWrited =0;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
BOOL bSuccess = TRUE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
bSuccess &= WriteFile(hSendWritePipeDup, (LPCVOID)szData, nSize, &dwWrited, NULL);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
CloseHandle(hSendWritePipeDup);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( !bSuccess )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
::LogMsg("WriteFile failed!");
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return FALSE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return TRUE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
BOOL CreateGameProcess()
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
char strDir[MAX_PATH] =
{0};
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
char strPath[MAX_PATH]=
{0};
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
GetCurrentDirectory(MAX_PATH,strDir);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcpy(strPath,strDir);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
#ifdef _DEBUG
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
const char* pszFileName = "\\main_debug.exe";
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
#else
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
const char* pszFileName = "\\main.exe";
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
#endif
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
strcat(strPath,pszFileName);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if ( !CreatePipe() )
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
::LogMsg("CreatePipe failed!");
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return FALSE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
STARTUPINFO starinfo =
{0};
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
starinfo.cb = sizeof(starinfo);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
starinfo.hStdInput = hSendReadPipe;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
starinfo.hStdOutput= hRecvWritePipe;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
starinfo.hStdError = hRecvWritePipe;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
starinfo.dwFlags |= STARTF_USESTDHANDLES;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
PROCESS_INFORMATION processinfo =
{0};
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
BOOL bRet =::CreateProcess(strPath, " fromlogin", NULL,NULL,TRUE,NULL,NULL,strDir,&starinfo,&processinfo);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if(bRet)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
// WaitForInputIdle(processinfo.hProcess,INFINITE);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
dwGameProcessID = processinfo.dwProcessId;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
CloseHandle(processinfo.hProcess);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
CloseHandle(processinfo.hThread);
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return TRUE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
::LogMsg("CreateProcess failed!");
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
return FALSE;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
子进程中接收数据:
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
DWORD dwReaded =0;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
HANDLE hRead = GetStdHandle(STD_INPUT_HANDLE);
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
HANDLE hWrite = GetStdHandle(STD_OUTPUT_HANDLE);
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
if( hRead )
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//*'从管道接收数据*/
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
const int nBufSize = 2048;
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
char szBuf[nBufSize];
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if(ReadFile(hRead, &szBuf,nBufSize, &dwReaded, NULL))
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)