管道的限制

管道限制

管道写入数据,读端没有读到原因:
一个管道的容量是有限的。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,即部分写入,写入时可能有其他进程穿插写入。

POSIX规定,少于 PIPE_BUF 的写操作必须原子完成,如果此时管道空闲缓冲区不足以容纳要写入的字节数,则进入睡眠,直到当缓冲区中能够容纳要写入的字节数时,才开始进行一次性写操作。
通过ulimit -a命令查看得知pipesize一项返回是8,单位是512bytes,也就是4K。获得的数据小于PIPE_BUF(在Linux上,PIPE_BUF为4096字节),管道空闲缓冲区进入等待。管道写端关闭,同时将数据写入空闲缓冲区,同时管道读端读取空闲缓冲区中的数据并获得管道写段关闭的信号,从而管道读端关闭。
解决办法:
修改管道限制大小:

//Linux上,可能不介意不可移植性,你可能对文件描述符操纵器F_SETPIPE_SZ感兴趣,这可以从Linux 2.6.35开始.
int pipe_sz = fcntl(pipe_des[1],F_SETPIPE_SZ,sizeof(size_t));

在调用之后会发现pipe_sz =getpagesize(),因为缓冲区不能小于系统页面大小.见man,fcntl(2).
如果当前linux版本没有到 2.6.35可以查看 2.6.35版本的源码,尝试补丁或者将将版本切换到linux 2.6.35

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值