同步、異步、阻塞、非阻塞和IO多路復用是怎么回事?


要想更好了解socket編程,有一個不可繞過的環節就是IO.
在Linux中,一切皆文件.實際上要文件干啥?不就是讀寫么?所以,這句話本質就是”IO才是王道”.用php的fopen打開文件關閉文件讀讀寫寫,這叫本地文件IO.在socket編程中,本質就是網絡IO.
所以,在開始進一步的socket編程前,我們必須先從概念上認識好IO.
如果到這里你還對IO沒啥概念,那么我就通過幾個詞來給你一個大概的印象:同步,異步,阻塞,非阻塞,甚至是同步阻塞,同步非阻塞,異步阻塞,異步非阻塞.是不是暈了?截至到目前為止,你可以簡單地認為只要搞明白這幾個名詞的含義以及區別,就算弄明白IO了,至少了可以繼續往下看了.
先機械記憶一波兒:IO分為兩大種,同步和異步.

同步IO:
阻塞IO
非阻塞IO
IO多路復用(包括select,poll,epoll三種)
信號驅動IO
異步IO
那么如何理解區別這幾個概念呢?尤其是同步和阻塞,異步和非阻塞,看起來就是一樣的.
我先舉個例子結合自己的理解來說明一下:

你去甜在心饅頭店買太極饅頭,阿梅說:"暫時沒,正在蒸呢,你自己看着點兒!".於是你就站在旁邊只等饅頭.此時的你,是阻塞的,是同步的.阻塞表現在你除了等饅頭,別的什么都不做了.同步表現在等饅頭的過程中,阿梅不提供通知服務,你不得不自己要等到"饅頭出爐"的消息.
你去甜在心饅頭店買太極饅頭,阿梅說:"暫時沒,正在蒸呢,你自己看着點兒!".於是你就站在旁邊發微信,然后問一句:"好了沒?",然后發QQ,然后再問一句:"好了沒?".此時的你,是非阻塞的,是同步的.非阻塞表現在你除了等饅頭,自己還干干別的時不時會主動問問饅頭好沒好.同步表現在等饅頭的過程中,阿梅不提供通知服務,你不得不自己要等到"饅頭出爐"的消息.
你去甜在心饅頭店買太極饅頭,阿梅說:"暫時沒,正在蒸呢,蒸好了我打電話告訴你!".但你依然站在旁邊只等饅頭,此時的你,是阻塞的,是異步的.阻塞表現在你除了等饅頭,別的什么都不做了.異步表現在等饅頭的過程中,阿梅提供電話通知"饅頭出爐"的消息,你只需要等阿梅的電話.
你去甜在心饅頭店買太極饅頭,阿梅說:"暫時沒,正在蒸呢,蒸好了我打電話告訴你!".於是你就走了,去買了雙新球鞋,看了看武館,總之,從此不再過問饅頭的事情,一心只等阿梅電話.此時的你,是非阻塞的,是異步的.非阻塞表現在你除了等饅頭,自己還干干別的時不時會主動問問饅頭好沒好.異步表現在等饅頭的過程中,阿梅提供電話通知"饅頭出爐"的消息,你只需要等阿梅的電話.
如果你仔細品過上面案例中的每一個字,你就能慢慢體會到之所以異步和非阻塞,同步和阻塞容易混淆,僅僅是因為二者的表現形式稍微有點兒相似而已.
阻塞和非阻塞關注的是:在等饅頭的過程中,你在干啥.
同步和異步關注的是:等饅頭這件事,你是一直等到"饅頭出爐"的結果,還是立即跑路等阿梅告訴你的"饅頭出爐".重點的是你是如何得知"饅頭出爐"的.
所以現實世界中,最傻的人才會采用異步阻塞的IO方式去寫程序.其余三種方式,更多的人都會選擇同步阻塞或者異步非阻塞.同步非阻塞最大的問題在於,你需要不斷在各個任務中忙碌着,導致你的大腦混亂,非常累.

那么IO多路到底屬於什么呢?比如epoll,其實嚴格意義上講,epoll是同步非阻塞,而並不是異步,但是很多文章里都說這種為異步,其實也談不上錯誤。說他是同步非阻塞是從嚴格意義上來考慮的,也就是嚴格按照unix環境高級編程的概念;說他異步非阻塞,實際上是從應用層面的同步異步來說的。
那么nginx是什么呢?其實nginx就是典型epoll應用,這就是為什么nginx能夠輕松應付並發過萬的原因,也就是說nginx就是基於epoll的異步非阻塞編程;相對來說,apache就是同步阻塞的典型案例了。如果apache需要應付高並發,就需要配置多個apache worker進程;而nginx只需要開啟少量worker就可以輕松應付!

 

轉:https://t.ti-node.com/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM