匿名管道实现进程间通信 为何管道数据不能重复读取

1:父进程创建管道private:HANDLEhWrite;//管道的写入句柄HANDLEhRead;//管道的读取句柄//初始化句柄CParentView::CPare... 1:父进程创建管道
private:
HANDLE hWrite;//管道的写入句柄
HANDLE hRead;//管道的读取句柄
//初始化句柄
CParentView::CParentView()
{
// TODO: add construction code here
hRead=NULL;
hWrite=NULL;
}
//关闭句柄
CParentView::~CParentView()
{
if(hRead)
CloseHandle(hRead);
if(hWrite)
CloseHandle(hWrite);
}
void CParentView::OnPipeCreate()
{
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;
//先把所有成员变量都设为0
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("..\\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);
}
}
2 写入数据
void CParentView::OnPipeWrite()
{
// TODO: Add your command handler code here
char buf[]="http://www.sunxin.org";
DWORD dwWrite;
if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
{
MessageBox("写入数据失败!");
return;
}
}
3 读取数据
void CParentView::OnPipeRead()
{
// TODO: Add your command handler code here
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
MessageBox("读取数据失败!");
return;
}
MessageBox(buf);
}
4 子进程写入数据
private:
HANDLE hWrite;
HANDLE hRead;
CChildView::CChildView()
{
hRead=NULL;
hWrite=NULL;
}
CChildView::~CChildView()
{
if(hRead)
CloseHandle(hRead);
if(hWrite)
CloseHandle(hWrite);
}
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;
}
}
5 子进程读取数据
void CChildView::OnPipeRead()
{
char buf[100];
DWORD dwRead;
if(!ReadFile(hRead,buf,100,&dwRead,NULL))
{
MessageBox("读取数据失败!");
return;
}
MessageBox(buf);
}

为什么只能读取一次,再点击读取就会假死,直到另一个进程写入管道数据
展开
 我来答
zrj_bd
2010-09-02 · TA获得超过1870个赞
知道小有建树答主
回答量:647
采纳率:100%
帮助的人:1107万
展开全部
你的if(!ReadFile(hRead,buf,100,&dwRead,NULL))(包括if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))
)方法是同步的,它只有在读取到数据或者出现问题的时候才会返回,因此你说的“再点击读取就会假死”其实是readfile函数阻塞了,一直在等待。
而你再次写入数据的时候,readfile就能够读取到数据,也就退出阻塞状态,返回了。
你可以用ReadFileEx,它是异步的,命名管道是可以用的,但是我不是很清楚匿名管道能不能用,你自己试试,或者干脆就使用命名管道方式
幸巴达
2010-09-03 · TA获得超过1.2万个赞
知道大有可为答主
回答量:6953
采纳率:38%
帮助的人:2484万
展开全部
没错, 读了一次后,缓冲区就空了, 在读的时候就等在那里知道缓冲区有新的内容。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
TT_RonG
2010-09-01 · TA获得超过156个赞
知道小有建树答主
回答量:168
采纳率:0%
帮助的人:240万
展开全部
因为缓冲区的数据已经被取走了,所以再次读取的时候,缓冲区是空的~~~里面无数据可读
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
万里猛_90992
2010-09-01
知道答主
回答量:79
采纳率:0%
帮助的人:30.3万
展开全部
只要输入
爱,龙啸爱的是余双
就好了·
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2010-09-01
展开全部
管道通信就像数据流一样,读出来了就表示从管道中GET下来了,GET下来就没了,除非另外一端重新再发
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
四念住
2010-09-02 · TA获得超过270个赞
知道小有建树答主
回答量:587
采纳率:0%
帮助的人:241万
展开全部
他是阻塞的同步函数啊.没数据到达.自然要等待了.直到有数据来了.他才接收.并函数返回.执行后面的函数
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
收起 更多回答(4)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式