(收藏)理解 I/O 多路复用 select/poll/epoll


https://huanxi.pub/2017/01/28/io%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8%E7%90%86%E8%A7%A3/
前段时间看了下 NIO ,发现里面有个 I/O 多路复用技术,但是听到这个名字一直觉得难以理解,什么是多路复用呢?好奇怪的名词,于是专门找了个时间仔细去了解了下。

客栈遇到的问题

从开始学习编程后,我就想开一个 Hello World 餐厅,由于一开始资金不足,所以只能开一个古老的小客栈。

客栈运营了几天,我发现我们的客栈存在着一个问题

我们的厨师只负责炒菜,炒好了放在一边继续炒其他菜,所以店小二必须经常进出厨房,一方面看看菜到底炒好了没有,如果炒好的话,就要把菜端出来,另一方面他必须得站在外面等候客人的其他需求。并且重要的是只有一个小二,他同时只能服务一个客人,其他客人必须等待
在客栈客人少的时候问题还不明显,有时候突然来个十几个客人,看到没人招待他,掉头就走了。

第一个解决方案(多线程)

给每一位顾客配备一名店小二。
这样一来,每一个顾客都有专门的小二负责,厨师一炒好菜,小二就将菜第一时间送到客人桌上,这样一来,客人的体验提升了很多,大家都非常满意,我客栈的名声也越来越好。

随着名声越来越好,客人也越来越多,渐渐地我发现,好像有什么地方不对。

随着客人越来越多,我必须招更多的店小二,支付更多的费用在小二身上,我发现,有时候付给员工的费用都比我赚的还多
第二个解决方案(select)

我将客栈进行改造,按照桌数区分,分为 1 2 3 4 四个区,每个区招一名店小二,来服务所在区的客人,并且对厨师进行了简单的培训,让他再炒好菜后大喊一声,有菜炒好了
这次简单升级后,我的客栈现在只有 4 个小二了,每个小二负责自己的区域,并且厨师炒好菜后,他大喊一声,来来来,菜炒好了,然后比如小二 1 号进入厨房,把菜端到他对应的区域挨个问,这菜是谁点的。

随着我的客栈越来越大越来越大,为了节省成本,我并没有再招更多的小二,依然是那四个小二。

直到有一天,1 区的客人爆满,达到了 1024 个了,那一天,我看着 1 区的小二每一次上菜几乎都是跑的,并且他告诉我,如果再多来一个客人,他就要挂了。
第三个解决方案(poll)

好吧,那个小二体力上好像跟不上节奏,所以我派人连夜赶工做了传说中的木牛流马来当店小二,这样一来,即使是 10240 个客人,一个木牛流马就 hold 住了
人数上限问题已经解决了,但是现在依然存在问题。

由于人数太多,每次要将做好的菜送到对应的客人桌上,必须挨个询问过去,这个步骤太慢了,很多次客人都不愿意等待而走掉了。
最终解决方案(epoll)

对木牛流马进行加工,使其可以记录每一个客人点的菜,然后厨师炒好菜后,只要报上菜名,木牛流马根据记录的订单,自动就将对应的菜端到客人桌中
有了这个解决方案,那么当一盘菜炒好后,就不必挨个确认是谁的菜了,如果新来了客人,同样只要记录下客人的菜单,提交给厨师,然后木牛流马又可以去招待其他客人了,当菜炒好后,直接就将菜送到客人那里了。

至此,生意兴荣,长盛不衰。

总结

select

只能监听 1024 个链接
并且没有返回具体可使用的 socket ,得挨个遍历
线程不安全
poll

没有链接数限制
依然线程不安全
epoll
解决了 select poll 的问题,并且指定了 socket 回调

猜你喜欢

转载自jackyrong.iteye.com/blog/2354925