欢迎各位学弟学妹收藏操作系统上机详解,大家有空也可以看看这篇文章哦——西电计科课程学习
实验4:匿名管道通信
一、实验目的
学习使用匿名管道在两个进程间建立通信。
二、实验内容
父进程创建一个匿名管道,在父子进程间建立通信。
三、程序框架
父进程:
先建一个Parent的单文档应用程序,增加“创建管道”“读取数据”“写入数据”三个菜单。
添加消息响应函数OnPipeCreate(),OnPipeRead(),OnPipeWrite()。在CParentView类中增加成员变量HANDLE类型的hRead,hWrite,初始化变量,并在析构函数中释放句柄:
void CParentView::OnPipeWrite()
{
if(!CreatePipe(…)) /*创建匿名管道*/
{
/*显示消息“创建管道失败!”*/
/*退出*/
}
if(!CreateProcess(…)) /*创建子进程*/
{
/*关闭句柄hRead、hWrite*/
/*显示消息“创建子进程失败!”*/
/*退出*/
}
}
void CParentView::OnPipeRead()
{
/*定义一个字符数组,用于存放读取的数据*/
if(!ReadFile(…)) /*读取数据*/
{
/*显示消息“读取数据失败!”*/
/*退出*/
}
/*打印读取的数据*/
/*退出*/
}
void CParentView::OnPipeWrite()
{
/*定义一个字符数组,用于存放写入的数据*/
if(!WriteFile(…)) /*写入数据*/
{
/*显示消息“写入数据失败!”*/
/*退出*/
}
}
子进程:
建一个Child的单文档,在CChildView中增加两个成员HANDLE型的成员变量hRead,hWrite,并添加消息响应函数OnPipeRead(),OnPipeWrite(),再添加虚函数OnInitialUpdate(),并在析构函数中释放句柄:
void CChildView::OnInitialUpdate()
{
hRead=GetStdHandle(…)/*获取标准输入句柄*/
hWrite=GetStdHandle(…)/*获取标准输出句柄*/
}
void CParentView::OnPipeRead()
{
/*定义一个字符数组,用于存放读取的数据*/
if(!ReadFile(…)) /*读取数据*/
{
/*显示消息“读取数据失败!”*/
/*退出*/
}
/*打印读取的数据*/
/*退出*/
}
void CParentView::OnPipeWrite()
{
/*定义一个字符数组,用于存放写入的数据*/
if(!WriteFile(…)) /*写入数据*/
{
/*显示消息“写入数据失败!”*/
/*退出*/
}
}
创建匿名管道:
BOOL CreatePipe( //创建匿名管道
PHANDLE hReadPipe, // read handle
PHANDLE hWritePipe, // write handle
LPSECURITY_ATTRIBUTES lpPipeAttributes, // security attributes
DWORD nSize // pipe size
);
创建子进程:
BOOL CreateProcess( //创建子进程
LPCTSTR lpApplicationName, // name of executable module
LPTSTR lpCommandLine, // command line string
LPSECURITY_ATTRIBUTES lpProcessAttributes, // SD
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
BOOL bInheritHandles, // handle inheritance option
DWORD dwCreationFlags, // creation flags
LPVOID lpEnvironment, // new environment block
LPCTSTR lpCurrentDirectory, // current directory name
LPSTARTUPINFO lpStartupInfo, // startup information
LPPROCESS_INFORMATION lpProcessInformation // process information
);
四、源代码
父进程消息响应函数:
void CParentView::OnPipeCreate()
{
// TODO: Add your command handler code here
//TODO: Add your command handler code here
SECURITY_ATTRIBUTES sa;
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
if(!CreatePipe(&hRead,&hWrite,&sa,0))
{
MessageBox("创建匿名管道失败!");
return;
}
STARTUPINFO sui;
PROCESS_INFORMATION pi;
ZeroMemory(&sui,sizeof(STARTUPINFO));
sui.cb=sizeof(STARTUPINFO);
sui.dwFlags=STARTF_USESTDHANDLES;
sui.hStdInput=hRead;
sui.hStdOutput=hWrite;
sui.hStdError=GetStdHandle(STD_ERROR_HANDLE);
if(!CreateProcess("C:\\Users\\HP\\Desktop\\OS实验\\实验4 匿名管道通信\\Child\\Debug\\Child.exe",NULL,NULL,NULL,
TRUE,0,NULL,NULL,&sui,&pi))
{
CloseHandle(hRead);
CloseHandle(hWrite);
hRead=NULL;
hWrite=NULL;
MessageBox("创建子进程失败!");
return;
}
else
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
void CParentView::OnReadPipe()
{
// TODO: Add your command handler code here
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
MessageBox("读取数据失败!");
return;
}
MessageBox(buf);
}
void CParentView::OnWritePipe()
{
// TODO: Add your command handler code here
char buf[]="I AM A XDUER.";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
MessageBox("写入数据失败!");
return;
}
}
子进程消息响应函数:
void CChildView::OnPipeRead()
{
// TODO: Add your command handler code here
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
MessageBox("读取数据失败!");
return;
}
MessageBox(buf);
}
void CChildView::OnPipeWrite()
{
// TODO: Add your command handler code here
char buf[]="这是一个匿名管道测试程序!";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
MessageBox("写入数据失败!");
return;
}
}
五、程序运行结果