免费注册 查看新帖 |

Chinaunix

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

关于验证linux不保证对管道的写操作具有原子性 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-08-31 18:25 |只看该作者 |倒序浏览
问题来源于ibm development上的一篇文章,有点不解其中关于"验证linux不保证对管道的写操作具有原子性"的方法

文章来自于http://www.ibm.com/developerworks/cn/linux/l-ipc/part1/index.html

对管道的写规则的验证2:linux不保证写管道的原子性验证
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
main(int argc,char**argv)
{
        int pipe_fd[2];
        pid_t pid;
        char r_buf[4096];
        char w_buf[4096*2];
        int writenum;
        int rnum;
        memset(r_buf,0,sizeof(r_buf));       
        if(pipe(pipe_fd)<0)
        {
                printf("pipe create error\n");
                return -1;
        }
       
        if((pid=fork())==0)
        {
                close(pipe_fd[1]);
                while(1)
                {
                sleep(1);       
                rnum=read(pipe_fd[0],r_buf,1000);
                printf("child: readnum is %d\n",rnum);
                }
                close(pipe_fd[0]);
               
                exit();
        }
        else if(pid>0)
        {
        close(pipe_fd[0]);//write
        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]);
        }       
}
输出结果:
the bytes write to pipe 1000
the bytes write to pipe 1000  //注意,此行输出说明了写入的非原子性
the bytes write to pipe 1000
the bytes write to pipe 1000
the bytes write to pipe 1000
the bytes write to pipe 120  //注意,此行输出说明了写入的非原子性
the bytes write to pipe 0
the bytes write to pipe 0
......


文中的关于验证 linux不保证 向管道写操作具有原子性操作的问题

再引用一下关于文中,关于read管道的原则:

"从管道中读取数据:
如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数为0;
当管道的写端存在时,如果请求的字节数目大于PIPE_BUF,则返回管道中现有的数据字节数,如果请求的字节数目不大于PIPE_BUF,则返回管道中现有数据字节数(此时,管道中数据量小于请求的数据量);或者返回请求的字节数(此时,管道中数据量不小于请求的数据量)。注:(PIPE_BUF在include/linux/limits.h中定义,不同的内核版本可能会有所不同。Posix.1要求PIPE_BUF至少为512字节,red hat 7.2中为4096)。"


在这个例子中关于验证写操作的原子性,大家注意如果我在子进程中修改 "rnum=read(pipe_fd[0],r_buf,1000);" 为 "rnum=read(pipe_fd[0],r_buf,4096);"
则显示输出结果:
child: readnum is 4096
child: readnum is 1024
child: readnum is 0
child: readnum is 0
child: readnum is 0
child: readnum is 0

/usr/include/linux/limits.h
#define PIPE_BUF        4096    /* # bytes in atomic write to a pipe */

我个人认为这跟read函数的缓冲区大小有关,这并不能证明linux不保证对管道写操作具有原子性。

另外还想问一下如何验证这个结果。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP