免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5062 | 回复: 19
打印 上一主题 下一主题

管道的问题(写的非原子性) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-04-25 22:38 |只看该作者 |倒序浏览

书上的一个例子:

#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <limits.h>
                                                                                
int main()
{
        int pipe_fd[2];
        pid_t pid;
        char r_buf[4096];
        char w_buf[4096*2];
        int writenum;
        int rnum=1;
        memset(r_buf,0,sizeof(r_buf));
        if(pipe(pipe_fd)<0)
        {
        printf("pipe error\n");
        return -1;
        }
        if((pid=fork())==0)//进入子进程
        {
        close(pipe_fd[1]);//关闭写
        while(rnum!=0)
        {
        sleep(1);
        rnum=read(pipe_fd[0],r_buf,1000);
        printf("child readnum is %d\n",rnum);
        }
        close(pipe_fd[0]);//关闭读
        exit(0);//子进程退出
        }
        else if(pid>0)//父进程
        {
        close(pipe_fd[0]);
        memset(r_buf,0,sizeof(r_buf));
        if((writenum=write(pipe_fd[1],w_buf,1024))==-1)
                printf("write to pipe error\n");
        else
                printf("the bytes write to pipe is %d \n",writenum);
        writenum=write(pipe_fd[1],w_buf,4096);
        close(pipe_fd[1]);
        }
        return 0;
}
运行结果:
[root@localhost work]# ./demo
the bytes write to pipe is 1024
child readnum is 1000
[root@localhost work]# child readnum is 1000
child readnum is 1000
child readnum is 1000    此行为什么说明了写入的非原子性?
child readnum is 1000
child readnum is 120   此行为什么说明了写入的非原子性?
child readnum is 0

我的系统为redhat 9.0...PIPE_BUF为4096字节
请高手回答.


[ 本帖最后由 天外飞客 于 2007-4-26 18:09 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-04-25 22:59 |只看该作者
代码太长了。

论坛徽章:
0
3 [报告]
发表于 2007-04-26 12:19 |只看该作者
这代码也长呀..
只是把字放大了点呀

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
4 [报告]
发表于 2007-04-26 12:23 |只看该作者
原帖由 天外飞客 于 2007-4-26 12:19 发表
这代码也长呀..
只是把字放大了点呀

关键是你干吗要把字放大?这样看着真的很费劲。

论坛徽章:
0
5 [报告]
发表于 2007-04-26 13:13 |只看该作者
我仔细看了代码,分析一下。见程序中的注释。

  1. #include <unistd.h>
  2. #include <sys/types.h>
  3. #include <errno.h>
  4. #include <limits.h>
  5.                                                                                 
  6. int main()
  7. {
  8.         int pipe_fd[2];
  9.         pid_t pid;
  10.         char r_buf[4096];
  11.         char w_buf[4096*2];
  12.         int writenum;
  13.         int rnum=1;
  14.         memset(r_buf,0,sizeof(r_buf));
  15.         if(pipe(pipe_fd)<0)
  16.         {
  17.         printf("pipe error\n");
  18.         return -1;
  19.         }
  20.         if((pid=fork())==0)//进入子进程
  21.         {
  22.         close(pipe_fd[1]);//关闭写
  23.         while(rnum!=0)
  24.         {
  25.         sleep(1);
  26.         rnum=read(pipe_fd[0],r_buf,1000);
  27.         printf("child readnum is %d\n",rnum);
  28.         }
  29.         close(pipe_fd[0]);//关闭读
  30.         exit(0);//子进程退出
  31.         }
  32.         else if(pid>0)//父进程
  33.         {
  34.         close(pipe_fd[0]);
  35.         memset(r_buf,0,sizeof(r_buf));
  36.         if((writenum=write(pipe_fd[1],w_buf,1024))==-1)
  37.                 printf("write to pipe error\n");
  38.         else
  39.                 printf("the bytes write to pipe is %d \n",writenum);
  40.         writenum=write(pipe_fd[1],w_buf,4096);
  41.         close(pipe_fd[1]);
  42.         }
  43.         return 0;
  44. }
  45. 运行结果:
  46. [root@localhost work]# ./demo
  47. the bytes write to pipe is 1024
  48. child readnum is 1000
  49. [root@localhost work]# child readnum is 1000
  50. child readnum is 1000
  51. child readnum is 1000    此行为什么说明了写入的非原子性?  //这个地方不知道为什么
  52. child readnum is 1000
  53. child readnum is 120   此行为什么说明了写入的非原子性?    //此地方当然证明了写入的非原子性,因为非原子性表示写入可能不会一次完成,也就是可以阻塞的。这个地方由于PIPI_BUF是4096,所以,你再次写入4096的时候,PIPE已经满了,所以,这个地方要阻塞,等待读PIPE到来,读取之后,才能再往里边写。
  54. child readnum is 0

复制代码

论坛徽章:
0
6 [报告]
发表于 2007-04-26 18:10 |只看该作者
现在可以了吧?
谁给解释下啊.谢谢啦

论坛徽章:
0
7 [报告]
发表于 2007-04-26 19:11 |只看该作者
原帖由 天外飞客 于 2007-4-26 18:10 发表
现在可以了吧?
谁给解释下啊.谢谢啦


晕。上边不是已经给了解释么???

论坛徽章:
0
8 [报告]
发表于 2007-04-26 19:16 |只看该作者
解释有点问题的~~没解释完啊.

论坛徽章:
0
9 [报告]
发表于 2007-04-26 19:18 |只看该作者
看了其他的参考..
写4096下的是原子性的,不过这个原子是可以分2段的..还是1次..
最后还是没明白

论坛徽章:
0
10 [报告]
发表于 2007-04-26 20:52 |只看该作者
原帖由 goooogo 于 2007-4-26 13:13 发表
我仔细看了代码,分析一下。见程序中的注释。
[code]
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <limits.h>
                                    ...


试了一下代码,好像一次写入>4096也可以。
这个真是不好解释。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP