操作系统----阻塞读终端

摘自《linux C语言编程一站式学习》
阻塞读终端
例子:
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
char buf[10];
int n;
n = read(STDIN_FILENO, buf, 10);
if (n < 0) {
perror("read STDIN_FILENO");
exit(1);
}
write(STDOUT_FILENO, buf, n);
return 0;
}
执行结果如下:
$ ./a.out
hello(回车)
hello
$ ./a.out
hello world(回车)
hello worl$ d
bash: d: command not found
分析:
第一次执行a.out的结果很正常,而第二次执行的过程有点特殊,现在分析一下:
1. Shell进程创建a.out进程, a.out进程开始执行,而Shell进程睡眠等待a.out进程退出。
2. a.out调用read时睡眠等待,直到终端设备输入了换行符才从read返回, read只读走10个字
符,剩下的字符仍然保存在内核的终端设备输入缓冲区中。
3. a.out进程打印并退出,这时Shell进程恢复运行, Shell继续从终端读取用户输入的命令,于
是读走了终端设备输入缓冲区中剩下的字符d和换行符,把它当成一条命令解释执行,结果发
现执行不了,没有d这个命令。
--------------------------------------------------分割线-------------------------------------------------------------
不阻塞读终端

如果在open一个设备时指定了O_NONBLOCK标志, read/write就不会阻塞。以read为例,如果设备暂
时没有数据可读就返回-1,同时置errno为EWOULDBLOCK(或者EAGAIN,这两个宏定义的值相同),
表示本来应该阻塞在这里( would block,虚拟语气),事实上并没有阻塞而是直接返回错误,调用
者应该试着再读一次( again)。这种行为方式称为轮询( Poll) ,调用者只是查询一下,而不是阻
塞在这里死等,这样可以同时监视多个设备:
while(1) {
非阻塞read(设备1);      //在linux系统中,设备1对应目录树下的一个设备文件,也就是文件 ,即read(文件名)
if(设备1有数据到达)
处理数据;
非阻塞read(设备2);      //在linux系统中,设备2对应目录树下的一个设备文件
if(设备2有数据到达)
处理数据;
...
}

如果read(设备1)是阻塞的,那么只要设备1没有数据到达就会一直阻塞在设备1的read调用上,即使
设备2有数据到达也不能处理,使用非阻塞I/O就可以避免设备2得不到及时处理。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值