九.linux中的高级IO

笔记地址:https://note.youdao.com/ynoteshare1/index.html?id=09f9fa91b90576adac4640f48b9210a3&type=note

前面第一节我们学习了对IO的open、read、write等阻塞式文件操作,这一篇我们将会学习对IO的一些高级操作。 2019/04/30 20:51

目录

一、非阻塞IO的引入

1、阻塞与非阻塞

2、如何修改阻塞为非阻塞

二.阻塞式IO的困境(举例)

1、程序中读取键盘

2、程序中读取鼠标

 

3、程序中同时读取键盘和鼠标

 

4、问题分析

三.并发式IO的解决方案

1、非阻塞式IO

2、利用两个进程实现同时读键盘和鼠标

3、多路复用IO

IO多路复用原理

select函数

select函数测试用例

poll函数

poll函数测试用例

4、异步通知(异步IO)

何为异步IO

异步IO设置的步骤如下:

 

5、存储映射IO

1、存储映射的好处

2、存储映射IO的特点

3、存储映射IO需要使用mmap函数,这里,我们暂不学习。


一、非阻塞IO的引入

1、阻塞与非阻塞

  • a) 函数操作文件时,因文件类型而阻塞,阻塞与函数本身无关

·读某些文件:由于数据不存在会导致调用者永远阻塞

 读管道文件:管道是进程间通信用的特殊文件,读管道时,如果管道中并无数据会导致

 对管道的读操作会阻塞。

  •  b) 写某些文件:在写某些文件时,当文件不能立即接收写入的数据时,也可能会导致
  • c) 某些函数本身就是阻塞的

wait、pause、sleep等函数以及某些进程间通信的函数(如当消息队列的消息接受函数设置了阻塞时),这些函数调用本身就是阻塞的

 

2、如何修改阻塞为非阻塞

通过前面的学习,我们知道某些文件默认打开后默认对文件的操作就是阻塞的,但是利用对文件描述符设置,可将其操作设置为非阻塞的,主要的方法有如下两种:

  • 1)打开文件时指定非阻塞,以非阻塞的方式打开标准输入文件(O_NONBLOCK函数,指定为了非阻塞)

 

int main(void){

int fd = -1;

fd = open("/dev/stdin", O_RDONLY|O_NONBLOCK);

if(fd < 0){

perror("open stdin is fail");

exit(-1);

}

return 0;

}

 

  • 2)将已经打开了的文件描述符设置为非阻塞的

(用fcntl函数进行设置,具体可查看第一节对fcntl函数的梳理)

int main(void)

{

int fd = -1, flag = -1;

/* F_GETFL:获取描述符原有状态给flag的命令,目的是为了保护原有的状态

* STDIN_FILENO:指向标准输入文件的文件描述符0 */

flag = fcntl(STDIN_FILENO, F_GETFL);

flag |= O_NONBLOCK;//将原有文件状态 | 非阻塞标志

//将修改后的包含了非阻塞标志的新状态重新设置回去

fcntl(STDIN_FILENO, F_SETFL, flag);

return 0;

}

 

二.阻塞式IO的困境(举例)

1、程序中读取键盘

int main(void)

{

// 读取键盘

// 键盘就是标准输入,故为0号文件描述符,stdin

char buf[100];

memset(buf, 0, sizeof(buf));

printf("before read.\n");

read(0, buf, 5);

printf("读出的内容是:[%s].\n", buf);

return 0;

}

 

2、程序中读取鼠标

我们鼠标的驱动文件如下:当查看mouse1,移动鼠标,并没有数据,当查看mouse0时,有乱码的数据,故我们的鼠标设备文件为:mouse0

int main(void)

{

// 读取鼠标

int fd = -1;

char buf[200];

fd = open("/dev/input/mouse0", O_RDONLY);

if (fd < 0)

{

perror("open:");

return -1;

}

memset(buf, 0, sizeof(buf));

printf("before read.\n");

read(fd, buf, 50);

printf("读出的内容是:[%s].\n", buf);

return 0;

}

 

3、程序中同时读取键盘和鼠标

int main(void)

{

// 读取鼠标

int fd = -1;

char buf[200];

fd = open("/dev/input/mouse1", O_RDONLY);

if (fd < 0)

{

perror("open:");

return -1;

}

memset(buf, 0, sizeof(buf));

printf("before 鼠标 read.\n");

read(fd, buf, 50);

printf("鼠标读出的内容是:[%s].\n", buf);

// 读键盘

memset(buf, 0, sizeof(buf));

printf("before 键盘 read.\n");

read(0, buf, 5);

printf("键盘读出的内容是:[%s].\n", buf);

return 0;

}

 

4、问题分析

(程序上设计是先读取鼠标,再读取键盘),如果顺序用反了,会怎么样???

 

运行程序时由于先读的是鼠标,它阻塞了键盘,所以我们先键盘敲入数据是没有用的,当移动鼠标后,鼠标数据打印

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值