《3.linux应用编程和网络编程-第3部分-3.6.高级IO》3.6.1.非阻塞IO 3.6.2.阻塞式IO的困境 3.6.3.并发式IO的解决方案 O_NONBLOCK

3.6.1.非阻塞IO
3.6.1.1、阻塞与非阻塞
3.6.1.2、为什么有阻塞式
(1)常见的阻塞:wait、pause、sleep等函数;read或write某些文件时
(2)阻塞式的好处:有利于操作系统性能的发挥,
3.6.1.3、非阻塞
(1)为什么要实现非阻塞
(2)如何实现非阻塞IO访问:O_NONBLOCK和fcntl
 

3.6.2.阻塞式IO的困境
3.6.2.1、程序中读取键盘

#include <stdio.h>
#include <unistd.h>
#include <string.h>


int main(void)
{
	char buf[100]; /* 定义一个buf */
	
	
	
	memset(buf, 0, sizeof(buf));/* 清空 buf */
	
	printf("before read \n");
	
	//读取键盘
	//键盘就是标准输入,stdin
	read(0,buf,2);  /* 从文件描述符 0 (0就是标准输入) 中 读取 2 个 字节,放到 buf 中 */
	//read 这个函数默认是 阻塞的, 如果我们不按键盘的 话,程序一直阻塞在这里

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

	
	return 0;
}


运行结果:


3.6.2.2、程序中读取鼠标

1. 怎么找 鼠标的 设备文件 描述符
root@ubuntu:/home/aston# ls /dev/input/
by-id  by-path  event0  event1  event2  event3  mice  mouse0  mouse1

cat /dev/input/mouse1  用cat 测试 mouse1

以上 是确定 mouse1 是鼠标的设备文件

代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int main(void)
{
    char buf[100]; /* 定义一个buf */
    int fd = -1;/* 定义设备文件描述符 */
    
    fd = open("/dev/input/mouse1", O_RDONLY);   /* open 打开mouse1 文件描述符, O_RDONLY 只读的文件打开 */
    if (fd < 0)    /* open 返回的 fd 小于 0,说明打开错误 */
    {
        perror("open:");
        return -1;
    }
    
    memset(buf, 0, sizeof(buf));/* 清空 buf */
    
    printf("before read \n");
    
    //读取鼠标
    read(fd,buf,5);  /*  此时fd 就是 mouse1 ,从fd (mouse1)中 读取 5 个 字节,放到 buf 中 */
    //read 这个函数默认是 阻塞的, 如果我们不按键盘的 话,程序一直阻塞在这里

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

    
    return 0;
}


运行结果:

 

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

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>




int main(void)
{
	char buf[100]; /* 定义一个buf */
	int fd = -1;/* 定义设备文件描述符 */
	
	fd = open("/dev/input/mouse1", O_RDONLY);   /* open 打开mouse1 文件描述符, O_RDONLY 只读的文件打开 */
	if (fd < 0)    /* open 返回的 fd 小于 0,说明打开错误 */
	{
		perror("open:");
		return -1;
	}
	
	//读取鼠标
	memset(buf, 0, sizeof(buf));/* 清空 buf */
	
	printf("before 鼠标 read \n");
	
	read(fd,buf,5);  /*  此时fd 就是 mouse1 ,从fd (mouse1)中 读取 5 个 字节,放到 buf 中 */
	//read 这个函数默认是 阻塞的, 如果我们不按键盘的 话,程序一直阻塞在这里

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

	
	
	//读取键盘
	memset(buf, 0, sizeof(buf));/* 清空 buf */
	
	printf("before 键盘 read \n");
	
	read(0,buf,5);  /*  从文件描述符 0 (0就是标准输入) 中 读取 2 个 字节,放到 buf 中 */
	//read 这个函数默认是 阻塞的, 如果我们不按键盘的 话,程序一直阻塞在这里

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

运行结果:

 
3.6.2.4、问题分析

 当 程序中同时读取键盘和鼠标时,因为都是 阻塞 式 的, 只能按照 程序的顺序,先读取鼠标,在读取键盘, 我们实际使用时,并不是这样的,所有这是 阻塞式的 困境!!

 

3.6.3.并发式IO的解决方案: 鼠标 和 键盘 同时并发
3.6.3.1、非阻塞式IO

https://blog.csdn.net/liangzuzong/article/details/130536354

代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>




int main(void)
{
	char buf[100]; /* 定义一个buf */
		
	int flag = -1, fd = -1, ret = -1;
	
	fd = open("/dev/input/mouse1", O_RDONLY | O_NONBLOCK);   /* open 打开mouse1 文件描述符, O_RDONLY 只读的文件打开,  O_NONBLOCK  非阻塞 属性 */
	
	// 把 0 号文件描述符(标准输入stdio) ,变成非阻塞式
	flag = fcntl(0, F_GETFL);   /* 先获取 原来的 flag 。 F_GETFL 获取文件访问模式和文件状态标志*/
	flag |= O_NONBLOCK;    /* 添加 非阻塞 属性 */
	fcntl(0, F_SETFL, flag);  /* 更新 flag */
	/* 以上这 3 步之后 ,标准输入0 ,就变成了 非阻塞式了  */
	
	
	while(1)
	{	
		//读取键盘
		memset(buf, 0, sizeof(buf));/* 清空 buf */
		ret = read(0,buf,5);  /*  从文件描述符 0 (0就是标准输入) 中 读取 2 个 字节,放到 buf 中 */
			//read 这个函数,标准输入 0 添加 O_NONBLOCK是 非 阻塞的,
			
		if(ret > 0)
		{
			printf("键盘读出的内容是:[%s] \n", buf);
		}

		
		
		//读取鼠标
		memset(buf, 0, sizeof(buf));/* 清空 buf */
		ret = read(fd,buf,5);  /*  此时fd 就是 mouse1 ,从fd (mouse1)中 读取 5 个 字节,放到 buf 中 */
			//read 这个函数,fd(此时是鼠标) 添加 O_NONBLOCK是 非 阻塞的,
		if(ret > 0)
		{	
			printf("鼠标读出的内容是:[%s] \n", buf);
		}
	}

	
	return 0;
}


运行结果: 缺点 性能不是最优!


3.6.3.2、多路复用IO
3.6.3.3、异步通知(异步IO)

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大漠飞鹰6666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值