Linux网络编程的5种IO模型一阻塞IO与非阻塞IO(内含现实生活举例说明)通俗易懂【建议新手收藏】

前言:整理之前学习socket编程的时候复习到了多路复用,搜索了有关资料,了解到多路复用也有局限性,本着打破砂锅问到底的精神,最终找到了关于IO模型的知识点。

一、概述

在《Unix网络编程》一书中提到了五种IO模型,分别是:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO以及异步IO。

我们在这里就介绍并实现这5种模型。介绍之前,请允许我引用某段比喻

阻塞IO, 给女神发一条短信, 说我来找你了, 然后就默默的一直等着女神下楼, 这个期间除了等待你不会做其他事情, 属于备胎做法.

非阻塞IO, 给女神发短信, 如果不回, 接着再发, 一直发到女神下楼, 这个期间你除了发短信等待不会做其他事情, 属于专一做法.

IO多路复用, 是找一个宿管大妈来帮你监视下楼的女生, 这个期间你可以些其他的事情. 例如可以顺便看看其他妹子,玩玩王者荣耀, 上个厕所等等. IO复用又包括 select, poll, epoll 模式. 那么它们的区别是什么?

  • 1)select大妈 每一个女生下楼, select大妈都不知道这个是不是你的女神, 她需要一个一个询问,
    并且select大妈能力还有限, 最多一次帮你监视1024个妹子
  • 2) poll大妈不限制盯着女生的数量, 只要是经过宿舍楼门口的女生, 都会帮你去问是不是你女神
  • 3)epoll大妈不限制盯着女生的数量, 并且也不需要一个一个去问. 那么如何做呢?epoll大妈会为每个进宿舍楼的女生脸上贴上一个大字条,上面写上女生自己的名字, 只要女生下楼了,epoll大妈就知道这个是不是你女神了, 然后大妈再通知你. 上面这些同步IO有一个共同点就是, 当女神走出宿舍门口的时候,你已经站在宿舍门口等着女神的, 此时你属于阻塞状态

接下来是异步IO的情况:
你告诉女神我来了, 然后你就去打游戏了, 一直到女神下楼了, 发现找不见你了, 女神再给你打电话通知你, 说我下楼了, 你在哪呢? 这时候你才来到宿舍门口。 此时属于逆袭做法

二、阻塞IO 与 非阻塞IO

在Linux 系统编程中,我们在有关概念 章节中介绍了阻塞的概念。那么也很容易理解什么是阻塞IO与非阻塞IO。直接看图

1、阻塞IO

最传统的一种IO模型,即在读写数据过程中会发生阻塞现象。

当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block状态。
在这里插入图片描述
代码如下:

	printf("Calling recv(). \n");
	ret =  recv(socket, recv_buf, sizeof(recv_buf), 0); 
	printf("Had called recv(). \n");

也许有人会说,可以采用多线程+ 阻塞IO 来解决效率问题,但是由于在多线程 + 阻塞IO 中,每个socket对应一个线程,这样会造成很大的资源占用,并且尤其是对于长连接来说,线程的资源一直不会释放,如果后面陆续有很多连接的话,就会造成性能上的瓶颈。

2、非阻塞IO

当用户线程发起一个IO操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送IO操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。

在非阻塞IO模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU。

对于非阻塞IO就有一个非常严重的问题,在while循环中需要不断地去询问内核数据是否就绪,这样会导致CPU占用率非常高,因此一般情况下很少使用while循环这种方式来读取数据。

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

while(1)
{
    
    
	printf("Calling recv(). \n");
	ret =  recv(socket, recv_buf, sizeof(recv_buf), 0); 
	if (EAGAIN == ret) {
    
    continue;}
    else if(ret > -1) {
    
     break;}
	printf("Had called recv(), retry.\n");
}

小编推荐自己的linuxC/C++语言技术交流群:【1106675687】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_50662680/article/details/113184748