Linux select/poll机制原理分析

前言

  • Read the fucking source code! --By 鲁迅
  • A picture is worth a thousand words. --By 高尔基
1. 概述linux系统在访问设备的时候,存在以下几种IO模型:
  1. Blocking IO Model,阻塞IO模型;
  2. Nonblocking I/O Model,非阻塞IO模型;
  3. I/O Multiplexing Model,IO多路复用模型;
  4. Signal Driven I/O Model,信号驱动IO模型;
  5. Asynchronous I/O Model,异步IO模型;
【Linux select/poll机制原理分析】今天我们来分析下IO多路复用机制,在Linux中是通过select/poll/epoll机制来实现的 。
先看一下阻塞IO模型与非阻塞IO模型的特点:
Linux select/poll机制原理分析

文章插图
 
  • 阻塞IO模型:在IO访问的时候,如果条件没有满足,会将当前任务切换出去,等到条件满足时再切换回来 。
    • 缺点:阻塞IO操作,会让处于同一个线程的执行逻辑都在阻塞期间无法执行,这往往意味着需要创建单独的线程来交互 。
  • 非阻塞IO模型:在IO访问的时候,如果条件没有满足,直接返回,不会block该任务的后续操作 。
    • 缺点:非阻塞IO需要用户一直轮询操作,轮询可能会来带CPU的占用问题 。
对单个设备IO操作时,问题并不严重,如果有多个设备呢?比如,在服务器中,监听多个Client的收发处理,这时候IO多路复用就显得尤为重要了,来张图:
Linux select/poll机制原理分析

文章插图
 
如果这个图,让你有点迷惑,那就像个男人一样,man一下select/poll函数吧:
  • select:

Linux select/poll机制原理分析

文章插图
 
  • poll

Linux select/poll机制原理分析

文章插图
 
简单来说,select/poll能监听多个设备的文件描述符,只要有任何一个设备满足条件,select/poll就会返回,否则将进行睡眠等待 。看起来,select/poll像是一个管家了,统一负责来监听处理了 。
已经迫不及待来看看原理了,由于底层的机制大体差不多,我将选择select来做进一步分析 。
2. 原理2.1 select系统调用从select的系统调用开始:
Linux select/poll机制原理分析

文章插图
 
  • select系统调用,最终的核心逻辑是在do_select函数中处理的,参考fs/select.c文件;
  • do_select函数中,有几个关键的操作:
  • 初始化poll_wqueues结构,包括几个关键函数指针的初始化,用于驱动中进行回调处理;
  • 循环遍历监测的文件描述符,并且调用f_op->poll()函数,如果有监测条件满足,则会跳出循环;
  • 在监测的文件描述符都不满足条件时,poll_schedule_timeout让当前进程进行睡眠,超时唤醒,或者被所属的等待队列唤醒;
  • do_select函数的循环退出条件有三个:
  • 检测的文件描述符满足条件;
  • 超时;
  • 有信号要处理;
  • 在设备驱动程序中实现的poll()函数,会在do_select()中被调用,而驱动中的poll()函数,需要调用poll_wait()函数,poll_wait函数本身很简单,就是去回调函数p->_qproc(),这个回调函数正是poll_initwait()函数中初始化的__pollwait();
所以,来看看__pollwait()函数喽 。
2.2 __pollwait
Linux select/poll机制原理分析

文章插图
 
  • 驱动中的poll_wait函数回调__pollwait,这个函数完成的工作是向struct poll_wqueue结构中添加一条poll_table_entry;
  • poll_table_entry中包含了等待队列的相关数据结构;
  • 对等待队列的相关数据结构进行初始化,包括设置等待队列唤醒时的回调函数指针,设置成pollwake;
  • 将任务添加到驱动程序中的等待队列中,最终驱动可以通过wake_up_interruptile等接口来唤醒处理;
这一顿操作,其实就是驱动向select维护的struct poll_wqueue中注册,并将调用select的任务添加到驱动的等待队列中,以便在合适的时机进行唤醒 。所以,本质上来说,这是基于等待队列的机制来实现的 。
是不是还有点抽象,来看看数据结构的组织关系吧 。
2.3 数据结构关系
Linux select/poll机制原理分析

文章插图