管道的原子性 linux写操作原子性

从本质上说,管道也是一种文件,但他又和一般的文件有所不同,管道可以克服使用文件进行通信的两个问题

限制管道的大小。实际上,管道是一个固定大小的缓冲区。在Linux中该换冲区的大小为一页,4k

使得他的大小不像文件那样不加检验的增长。使用固定缓冲区也会带来问题,比如再写管道时可能变满

当这种情况发生时,随后对管道的write()调用被阻塞,等待某些数据被读取,以便腾出足够的空间供

write()调用。

读取工作也可能比写的进程快。当所有进程的数据被读取完时,一个随后的read()调用将默认的被阻塞、

管道变空。这种情况发生时,一个随后的read()调用将被默认的阻塞,等待某些数据被写入,这样就解决了read()

调用将被默认的阻塞,等待某些数据将被写入,这解决了read()调用返回文件结束的问题。

一个管道的容量是有限的。POSIX规定,少于 PIPE_BUF 的写操作必须原子完成:要写的数据应被连续的写到管道;大于 PIPE_BUF 的写操作可能是非原子的: 内核可能会把此数据与其它进程的对此管道的写操作交替起来。POSIX规定PIPE_BUF至少为512B(linux中为4096B),具体的语义如下: 其中n为要写的字节数
    n <= PIPE_BUF, O_NONBLOCK无效:原子的写入n个字节。如果管道当前的剩余空间不足以立即写入n个字节,就阻塞直到有足够的空间。
    n <= PIPE_BUF, O_NONBLOCK有效:写入具有原子性,如果有足够的空间写入n个字节,write立即成功返回。否则一个都不写入,返回错误,并设置errno为EAGAIN。
    n >  PIPE_BUF, O_NONBLOCK无效:非原子写。可能会和其它的写进程交替写。write阻塞直到将n个字节写入管道。
    n >  PIPE_BUF, O_NONBLOCK有效:如果管道满,则write失败,返回错误,并将errno设置为 EAGIN。如果不满,则返回写入的字节数为1~n,即部分写入,写入时可能有其他进程穿插写入。

结论:
1、当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。
2、当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

原文地址:https://www.cnblogs.com/qiumingcheng/p/11325512.html

时间: 2024-11-05 16:26:09

管道的原子性 linux写操作原子性的相关文章

从头认识多线程-3.2 使用volatile声明的变量的写操作是非原子性的

这一章节我们来讨论一下使用volatile声明的变量的各种操作是非原子性的. 1.上一章节我们已经提到,volatile把工作内存里面变量的改变同步到主内存, 使得各个线程能够把该变量当成是整体的状态控制 2.但是,使用volatile声明的变量的写操作是非原子性的 代码清单: package com.ray.deepintothread.ch03.topic_2; public class VolatileTest extends Thread { private volatile int i

Linux数据写操作改进

Linux的IO操作中数据的写函数int nwrite = write(int fd,void* buf ,int len)表示向fd文件描述符写入len个字节长度的数据报文,但是这并不能保证真正向内核缓冲区写入了len个数据.比如当内核socket缓冲区不足,小于len个字节,则会只写入其中的一部分,返回nwrite表示实际写入的字节数:因为这种读写方式可以保证数据全部写入缓冲区,因此实际返回值只有-1表示写入错误,size表示完全写入缓冲区. 为了保证数据写入的完整性,采用循环的写入是非常必

你一定要知道的关于Linux文件目录操作的12个常用命令

写在前面: 1,<你一定要知道的关于Linux文件目录操作的12个常用命令>是楼主收集的关于Linux文件目录操作最常用的命令,包括文件或目录的新建.拷贝.移动.删除.查看等,是开发人员操作Linux系统的常用命令,所以你一定要知道. 2,<你一定要知道的关于Linux文件目录操作的12个常用命令>适合初学者,对于Linux大神的请绕过,不过欢迎一起讨论学习! 3,此次收集,多谢来自http://www.cnblogs.com/peida/archive/2012/10/23/27

Linux桌面操作系统性能分析学习总结

1.什么是计算机性能 所谓计算机的性能(Performance)通常是指计算机的速度,它是程序执行时间的倒数.而程序执行时间是指用户向计算机送入一个任务后,直到获得他需要的结果这一段等待时间. 包括: 1.访问磁盘和访问存储器的时间 2.CPU 运算时间 3.I/O 动作时间 4.操作系统的开销时间等. 2.Linux桌面操作系统性能分析意义 1.操作系统的性能直接影响了其上应用系统的性能 2.性能评估结果是用户在操作系统选购过程中的重要参考指标 3.为开发者优化操作系统的性能提供指导 4.为操

I/O重定向和管道——《Unix/Linux编程实践教程》读书笔记(第10章)

1.I/O重定向的概念与原因 及 标准输入.输出的标准错误的定义 所以的Unix I/O重定向都基于标准数据流的原理.三个数据了分别如下: 1)标准输入--需要处理的数据流 2)标准输出--结果数据流 3)标准错误输出--错误消息流 概念:所以的Unix工具都使用文件描述符0.1和2.标准输入文件的描述符是0,标准输出的文件描述符是1,而标准错误输出的文件描述符则是2.Unix假设文件描述符0.1.2已经被打开,可以分别进行读写操作. 通常通过shell命令行运行Unix系统工具时,stdin.

python通过SSH登陆linux并操作

使用python通过SSH登陆linux并操作 用的昨天刚接触到的库,在windows下通过paramiko来登录linux系统并执行了几个命令,基本算是初试成功,后面会接着学习的. 代码: >>> import paramiko >>> ssh = paramiko.SSHClient()>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())>>> ssh.conn

Linux 文件操作总结

http://blog.163.com/he_junwei/blog/static/19793764620152592737741/ ioctl?? lseek?? 文件是linux中的一个重要概念.在Linux中,一切(几乎一切)都是文件.简单的说,C中基本的的printf()函数,scanf()函数,其实都属于文件操作. 对于文件操作,虽然都是通过函数调用的方式实现,却还是能分为两类:系统调用和库函数. 这篇文章将先介绍linux中文件的概念,系统调用和库函数的概念 ,然后具体的讨论两种方式

Linux文件操作的常用系统函数说明

1. open打开文件 (man 2 open 查看) int open(const char *pathname, int flags); //pathname文件名(路径):flags打开模式,有O_RDONLY, O_WRONLY, O_RDWR int open(const char *pathname, int flags, mode_t mode); //该函数一般用于创建新文件,flags添加O_CREAT,比如:O_RDWR|O_CREAT int creat(const cha

关于Linux文件操作1.1

本文章记录本人在学习Linux中遇到的一些比较好的题目,给大家分享一下. 先来实验题目: 编程实现一个程序,功能是每一秒钟向屏幕打印当前系统时间,和当前行号示例如下 该程序应该无限循环,直到强制中断该进程为止(比如按Ctrl-C中断程序).接着再启动程序,将系统时间追加到原文件之后,并且序号能够接续上次的序号: 好了看完题目后我们应该想的是,实现这么一个功能我们需要什么知识? 我们实现功能的逻辑是什么? 我们在写代码中有什么细节需要注意的(PS:使代码尽善尽美!) a):  先花五分钟想一下这个