管道(匿名/命名管道)的写数据大小在不超过PIPE_BUF(65536字节)时,内核能保证操作的原子性。如果写入的数据大小超过PIPI_BUF,内核很有可能会把此数据与其它进程的对此管道的写操作交替起来,这样的话,数据就乱了。
POSIX规定,小于PIPE_BUF的写操作必须是原子操作:要写的数据应该被连续地写到管道;大于PIPE_BUF的写操作可能是非原子的:内核可能会将数据与其他进程写入的数据交织在一起。
n <= PIPE_BUF,O_NONBLOCK无效:原子的写入n个字节。如果管道当前的剩余空间不足以立即写入n个字节,就阻塞到有足够的空间;
n <= PIPE_BUF,O_NONBLOCK有效:写入具有原子性,如果有足够的空间写入n个字节,write立即成功返回。否则一个都不写,返回-1,并设置errno为EAGAIN;
n > PIPE_BUF,O_NONBLOCK无效:非原子写,可能会和其他的写进程交替写。write阻塞直到将n个字节写入管道;
n > PIPE_BUF,O_NONBLOCK有效:如果管道满,则write失败,返回-1,并将errno设置为EAGAIN;如果不满,则返回写入的字节数为1~n,即部分写入,写入时可能有其他进程穿插写入。
结论:
1、当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性;
2、当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。
如还有疑问,请参考博客
管道的读写规则以及原子性问题