Linux:匿名管道的非阻塞属性

fcntl
函数有两个功能:

  1. 查看文件描述符属性
  2. 将文件描述符设置成非阻塞属性:O_NONBLOCK
    在这里插入图片描述
    在这里插入图片描述

为什么读端阻塞属性为0,非阻塞属性是2048;

  • 因为文件打开方式的宏为位图的使用方式;

  • 例如在之前使用open函数,为什么能使用按位或的方式能表示既可以读写,文件不存在时又可以创建:

  • open(“./1.txt”, O_RDWR | O_CREAT, 0664)
    0表示八进制,664是权限

操作系统内核本质上也是由代码构成的,O_RDWR ,O_CREAT这些宏在内核中是有定义的;内核源码定义:
在这里插入图片描述

1.
先查看fd[0]的原属性:

在这里插入图片描述

结论:

  • fd[0]的属性信息是0
  • 在内核源码中,O_RDONLY对应的八进制是全0,转化成十进制也是全0,所以说f[0]的是只读属性
  • 我们说fd[0]是管道的读端是因为其对应的文件描述符的属性为只读属性

2.
接下来再给fd[0]添加非阻塞属性

在这里插入图片描述

  • 在增加属性的时候一定要用或 |保留原属性,不保留那就是重新设置了一个新属性,之前的属性就都没有了
  • 第二次的属性是2048,相对于0多了一个非阻塞属性;
  • 以上验证了文件打开方式的宏,在内核中都是使用位图的方式进行计算的

在这里插入图片描述

匿名管道的非阻塞特性:

在这里插入图片描述

读端设置成非阻塞,只需要父进程写端,子进程读端

1.父进程写端不关闭;子进程一直读
在这里插入图片描述 调用read函数后,返回值为-1

  • 含义1.表示未在管道中读到内容
  • 含义2.表示在读管道时调用错误
  • 通过错误码区分,将errno置为EAGAIN表示1成立,应循环继续读取,这就是非阻塞要搭配循环的一种体现

2.父进程写端关闭;子进程一直读
在这里插入图片描述

  • 含义1.表示没有读到内容
  • 含义2.因为没有写端而返回(该情况成立)
  • 返回0后就不用搭配循环了,因为该种情况表示管道没有写端

代码2:
在这里插入图片描述

写端设置成非阻塞

父进程读,子进程写
因为最后一个结果会导致一个进程崩溃,设置子进程写,父进程读

1.写端设置成非阻塞,子进程写,父进程读

  • 子进程只写一次,父进程读端不关闭,正常输出
  • 子进程一种写,在管道写满之后返回-1;写满管道后再次调用write函数,返回-1
    在这里插入图片描述

2.写端设置成非阻塞,读端关闭,

  • 调用写就会崩溃,产生僵尸进程
    所有读端都关闭,子进程刚往管道中一些写,就收到信号,导致子进程崩溃在这里插入图片描述

谁设置成非阻塞,谁就是因变量,将另一方设置成自变量(关不关闭)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值