能说一下I/O多路复用吗?

引用知乎上一个高赞的回答来解释什么是I/O多路复用:

假设你是一位老师,需要让30个学生解答一道题目,然后检查学生们的答案是否正确。你有以下几个选择:

  1. 第一种选择是按顺序逐个检查学生的答案,先检查学生A,然后是学生B,再接着是学生C,以此类推。如果其中一个学生花费了很长时间解答问题,那么全班其他学生都需要等待,这样会导致效率低下。这种方式就好比使用循环逐个处理学生的答案,没有并发能力。
  2. 第二种选择是创建30个分身,每个分身负责检查一个学生的答案是否正确。每个分身独立运行,可以并行地处理每个学生的答案,但是需要创建大量的分身,增加了系统的开销。
  3. 第三种选择是你站在讲台上等待学生举手。当学生解答完毕后,他们会举手示意完成。你会下去依次检查举手的学生的答案,然后再回到讲台上等待其他学生的举手。这时,学生C和学生D举手,表示他们解答问题完毕,你会下去依次检查学生C和学生D的答案,然后继续回到讲台上等待其他学生的举手。接着,学生E和学生A举手,你会处理他们的答案。这种方式就是一种I/O复用模型。

在这个比喻中,第一种选择对应阻塞I/O模型,第三种选择对应I/O多路复用模型。

redis-eb541432-d68a-4dd9-b427-96c4dd607d64.png

在Linux系统中,有三种方式可以实现I/O多路复用:select、poll和epoll。以epoll为例,你将每个学生对应的学号注册到epoll中,然后epoll会帮助你监听哪些学生举手了,从而避免了对全班学生的轮询检查。此时,学生应该采用非阻塞模式。这样,整个过程中只有在进行select、poll、epoll等调用时才会阻塞,而收发学生答案的过程是非阻塞的。整个进程或线程可以充分利用起来,这就是事件驱动的反应器模式。

标签: java, Java面试题, Redis, Java问题合集, Java编程, Java问题精选, Java常见问题, Redis面试题