请教关于“多个进程往同一个匿名管道写数据”时的进程间数据同步问题

csuchao 2012-04-01 02:43:13
父进程A:
int main()
{
// 步骤1:创建一个匿名管道

// 步骤2:创建5子进程B,并重定向子进程的标准输出

// 步骤3:调用WaitForMultiObjects()等待5个子进程执行结束,通过GetTickCount()计算子进程执行花费的时间

// 步骤4:读取匿名管道中的内容到一个缓冲区中 char buffer[1024 * 4]

return 0;
}

子进程B:
int main()
{
DWORD dwCurProcessID = GetCurrentProcessId();

printf("%d: 00001111\n", dwCurProcessID);
Sleep(1000);

printf("%d: 00001111\n", dwCurProcessID);
Sleep(1000);

printf("%d: 00001111\n", dwCurProcessID);
Sleep(1000);

return 0;
}


// 疑问:
1. 等待5个子进程B执行完毕花费的时间不超过5s,而每个子进程B需要Sleep 3s,说明写匿名管道是异步的?
2. 父进程从匿名管道中读取到得数据是以下形式:
4896: 00001111
4896: 00001111
4896: 00001111
5012: 00001111
5012: 00001111
5012: 00001111
... ...
也就是说,数据是一个进程写完,才能够下一个进程往管道写数据,这是典型的同步模式?

那么,多个进程往一个匿名管道写数据,到底是同步还是异步?

我跟踪看了printf的实现代码,用的是旋转锁,该锁是用户对象,只能用于同一个进程内部的线程间同步,而上述场景是进程之间的线程同步,实验结果表明往管道写数据是经过同步的,那么说明匿名管道本身具有线程安全属性?
...全文
391 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
csuchao 2012-04-04
  • 打赏
  • 举报
回复
谢谢各位,问题已解决:
1. 匿名管道读写操作是原子安全的;
2. 匿名管道在无数据的情况下读数据是阻塞式的;
3. printf是带有缓冲区的,因此会等到缓冲区满后才会输出,产生了同步的假象;

注意:在实时性高的场合下,通过匿名管道进行标准输出重定位,每次printf()后,请调用fflush(stdout)强制刷新缓冲区,问题解决!
Lactoferrin 2012-04-01
  • 打赏
  • 举报
回复
支持多线程的crt的printf才能保证没问题
这个论坛已经出现过很多由于printf没同步导致的问题
csuchao 2012-04-01
  • 打赏
  • 举报
回复
偌大一个csdn,回答的人怎么这么少?
fzc_crystal 2012-04-01
  • 打赏
  • 举报
回复
友情帮顶
ouyh12345 2012-04-01
  • 打赏
  • 举报
回复
可以另起一个进程,专门写匿名管道
其它进程通过共享内存向这个进程push数据

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧