面经·同步(Sync)/异步(Async)阻塞(Block)/非阻塞(Unblock)四种调用方式和(网络)IO模型

网络应用需要处理的无非就是两大类问题,网络I/O数据计算。相对于后者,网络I/O的延迟,给应用带来的性能瓶颈大于后者。

概念

  • 概念1:阻塞与非阻塞
  • 概念2:同步与异步
  • 概念3:(网络)I/O模型 , 好像一般IO模型就是指网络IO模型

同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式

在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:

  • 同步/异步主要针对调用(请求)者(如Client端)  
    • 所谓同步,就是在c端发出一个功能调用时,在没有得到结果之前,调用者会一直等到有return,才会去做下一件事。
    • 异步的概念和同步相对。当c端一个异步过程调用发出后,调用者就可以去干其他事。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。
  • 阻塞/非阻塞主要针对被调用(被请求)者(如S端):
    • 阻塞,就是调用我(s端被调用者,函数),我(s端被调用者,函数)没有计算出结果之前,我不会返回。
    • 非阻塞,就是调用我(s端被调用者,函数),我(s端被调用者,函数)立即返回,这样的好处是调用者得到返回后可以继续做其他操作,实际的计算结果之后**通过select通知调用者。
  • 同步/异步是由c端自己控制,但是S端是否阻塞/非阻塞, C端完全不需要关心.

既然异步IO优势这么明显,那在所有项目里面只使用这一种不就好了?什么情况下会考虑其他的几种IO模型呢?

执行顺序难预期,不利于人类理解,开发调试困难。调用端按a、b、c的顺序发出,在被调用端的返回最终计算结果可能是c、b、a。

我的有道云笔记. 详细讲解四种调用方式:阻塞、非阻塞、同步、异步

(Linux)五种(网络)IO模型

  • 详细讲解见:用钓鱼的例子讲Linux五种网络IO模型
  • 1)阻塞I/O(blocking I/O)

  • 2)非阻塞I/O (nonblocking I/O) 

    • 被访问者没准备好数据的时候先返回error给访问者,访问进程干一会别的事在发起访问请求。反复前一个步骤(轮询)直到被访者准备好了数据。

  • 3) I/O复用(select 和poll) (I/O multiplexing)

    • 上文的轮询是用户态的操作,消耗大量CPU时间。用户态自己进行访问请求,然后轮询,并自己接收数据。

      select轮询和poll是内核级别操作。

      select调用可以等待多个socket,当其中任何一个socket的数据准好了,就能返回进行可读。

      多路复用I/O用select和poll替换了多路复用I/O。用户态将访问请求交接给select这个帮手,select进行轮询,用户态去select那接收数据。

      问题:最终接受数据的顺序,与访问请求的顺序不一致。

      对于多路复用,也就是轮询多个socket。钓鱼的时候,我们雇了一个帮手,他可以同时抛下多个钓鱼竿,任何一杆的鱼一上钩,他就会拉杆。他只负责帮我们钓鱼,并不会帮我们处理,所以我们还得在一帮等着,等他把收杆。我们再处理鱼。多路复用既然可以处理多个I/O,也就带来了新的问题,多个I/O之间的顺序变得不确定了,当然也可以针对不同的编号

    • select最老,是对数组套接字的轮询**

      • 对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低:

      • 需要维护大量fd

      • 基于数组实现,fd存储个数有限

    • poll本质上和select没有区别

      • 基于链表实现,fd存储个数没有限制

    • epoll最新,将socket组织在红黑树中,没有最大并发链接数限制

    • select和epoll就够用了

  • 4)信号驱动I/O (signal driven I/O (SIGIO))

  • 5)异步I/O (asynchronous I/O (the POSIX aio_functions))

  • 前四种都是同步IO

猜你喜欢

转载自blog.csdn.net/wzwdcld/article/details/81569851