- 论坛徽章:
- 0
|
问题来源于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不保证对管道写操作具有原子性。
另外还想问一下如何验证这个结果。 |
|