为什么代码显示写入管道不能确保原子性?
这是一个非常简单的程序。创建管道,然后fork,在父进程和子进程之间使用管道。 结果表明写入管道并不能确保原子性。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
int main(void)
{
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) //create pipe
{
printf("pipe create error\n");
return -1;
}
if((pid=fork())==0) //fork
{
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(EXIT_SUCCESS);
}
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]);
}
return EXIT_SUCCESS;
}
result:
the bytes write to pipe 1000
the bytes write to pipe 1000 //show write pipe not atomic
the bytes write to pipe 1000
the bytes write to pipe 1000
the bytes write to pipe 1000
the bytes write to pipe 120 //show write pipe not atomic
the bytes write to pipe 0
the bytes write to pipe 0
......
那么我想问 write atmoic 是什么意思?为什么这个程序会显示它?
This is a very simple program.create pipe,then fork,use pipe between parent and child process.
and the result show that write to pipe doesn't ensure atomic.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
int main(void)
{
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) //create pipe
{
printf("pipe create error\n");
return -1;
}
if((pid=fork())==0) //fork
{
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(EXIT_SUCCESS);
}
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]);
}
return EXIT_SUCCESS;
}
result:
the bytes write to pipe 1000
the bytes write to pipe 1000 //show write pipe not atomic
the bytes write to pipe 1000
the bytes write to pipe 1000
the bytes write to pipe 1000
the bytes write to pipe 120 //show write pipe not atomic
the bytes write to pipe 0
the bytes write to pipe 0
......
then i want to ask what does write atmoic mean?and why this program show it ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对不大于 PIPE_BUF 字节的管道的写入必须是原子的。这意味着,如果您有多个进程同时写入同一个管道,如果每个 write() 不超过 PIPE_BUF 字节,则它们的内容不会混合,从而允许您设置一个协议,而不是让多个写入器仅使用一个管道,只要您不需要更长的写入。
Writes to pipes not greater than PIPE_BUF bytes must be atomic. This means that if you have several processes writing concurrently to the same pipe, if every write() is of no more than PIPE_BUF bytes, their contents don't get intermixed, allowing you to setup a protocol than can have several writers using only one pipe, as long as you don't need longer writes.
了解有关原子性的更多信息此处
应确保所有共享数据结构的原子性多线程/处理系统。
这里有一些很好的例子
Learn more about Atomicity here
Atomicity should be ensured to all the shared data-structure in the multi-threaded/-processing systems.
There are some good examples here
您的程序及其结果并未表明写入不是原子的。写入是原子的意味着在单个
write()
中写入的字节只有在write()
完成之后才可用,并且当它们完成时才可用。是,全部都将可用。基本上,如果您可以读取任何字节,那么您就可以读取所有字节。您不必一下子读完它们;您可以选择仅read()
其中一部分,并在稍后的read()
中获取其余部分。如果多个write()
中有可用字节,您甚至可以从一个write()
读取所有字节(剩余的),并从下一个write()
读取一些字节。这里所有的原子性保证是,您不能仅读取某个write()
中的部分字节,但不能读取如果您选择的话,可以使用read()
其余部分。当然,只有当管道的缓冲区有空间容纳写入的字节时,才能保证原子写入——但您的程序不应达到限制。
Your program and its results do not show that the writes are not atomic. What it means for the writes to be atomic is that the bytes written in a single
write()
won't be available until after thewrite()
finishes, and when they are, all of them will be available. Basically, if you can read any of the bytes at all, you can read all of them. You don't have to read them all at once; you can choose toread()
only some of them, and get the rest in a laterread()
. If there are bytes available from more than onewrite()
, you can even read all the bytes (that are left) from onewrite()
and some from the next. All atomicity guarantees here is that you won't be able toread()
only some of the bytes from a certainwrite()
but unable toread()
the rest if you choose.Of course, atomic writes are only guaranteed if the pipe's buffer has room for the bytes written -- but your program shouldn't be reaching the limit.