zoukankan      html  css  js  c++  java
  • 管道的原子性 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将不再保证写入的原子性。
  • 相关阅读:
    get 请求 请求参数超出请求链接最大数 解决办法
    请求被中止: 未能创建 SSL/TLS 安全通道 .NET
    <![CDATA[解析 XML 出错 (位置: /body): <unspecified file>(1): expected <]]> 微信支付统一下单
    js之new一个对象原理
    键盘事件keydown、keypress、keyup
    mongo的runCommand与集合操作函数的关系
    (3.2)狄泰软件学院C++课程学习剖析三
    PAL制式和NTSC制式的区别
    入门视频采集与处理(BT656简介)
    视频内同步与外同步有什么区别
  • 原文地址:https://www.cnblogs.com/qiumingcheng/p/11325512.html
Copyright © 2011-2022 走看看