非阻塞IO原理和特性

  下文所说的IO,包含IO就绪和IO操作

  epoll 是一种Linux下的IO模型,是同步非阻塞的一种,也是当前比较流行的IO模型。

  Linux下IO模型大致可以分为:同步阻塞、同步非阻塞、异步。

  

  普通的非阻塞IO是各个IO自行盲询自己的IO是否就绪,而IO复用则是以一个系统调用来完成所有IO是否就绪的轮询,如果就绪则执行IO操作。

  事件驱动是IO复用的一种升级版本,IO复用是轮询所有的IO。

  而事件驱动是只处理已经就绪的IO,首先开启socket信号驱动的功能(将socket放到epoll文件系统里file对象对应的红黑树,并在内核终端处理程序中注册回调函数),当网卡检测到某个socket有数据来到时,内核就会将socket放入IO就绪队列,并从网卡拷贝数据到内核。

  IO复用的缺点

    单线程能轮询的文件描述符有限1024;

    需要轮询所有的IO,如果当前IO事件很多,但是就绪的非常少,那么会导致效率下降;

  事件驱动则可以解决上述两个缺点,没有文件描述符的限制(通常都非常大,比如2G内存的机器都有655350);只处理已经就绪的IO,可以过滤掉不活跃的IO轮询带来的损失。

  同时使用mmap(内存映射)的方式,来减少IO数据从内核-用户控件的拷贝。

    MMAP介绍:

      1、用户空间、内核空间都是不能直接访问设备的物理地址

      2、内核空间如果要访问设备的物理地址,需要先映射物理地址到内核的虚拟地址(页缓存)上,以后驱动程序访问这个虚拟地址

      3、用户空间只能通过系统调用访问映射好的内核虚拟地址(页缓存)

      这上面会有2次数据拷贝,硬件和内核空间,用户空间和内核空间。

    而MMAP的目的是将2次拷贝转换为1次拷贝,节约拷贝数据带来的消耗。

    将物理地址映射到一块内存,应用程序(用户区域)可以直接访问这块内存。

  事件驱动的缺点:

    如果各个IO都比较活跃,那么IO复用的全轮询也不会有太多的性能损失,但是注册socket驱动事件却会带来一些负担。

posted @ 2018-04-18 12:07  lion_eagle  阅读(2149)  评论(0编辑  收藏  举报