1、前言
前一段時間出去面試,被問到同步、異步與阻塞、非阻塞的區別。我一時半會沒有想出來,作為一個工作三年的人來說,實在很慚愧。我當時理解同步、異步屬于兩個進程中間的協作關系,例如使用瀏覽器訪問一個網站,需要多次請求服務端,才能加載完整個頁面的內容。同步的操作如下:瀏覽器首先發送第一個請求,等待服務器回復后,再發送第二個請求,依次類推,直到所有請求完成。異步的操作如下:瀏覽器發送第一個請求,可以不用等待服務器返回,可以繼續發送第二個請求。阻塞與非阻塞屬于進程的API執行動作的方式,例如進行需要read數據,阻塞方式操作流程是:如果沒有數據,則read會一直等著數據到來,才能進行后續的動作;而非阻塞則是read沒有到數據后,則可以進行后續的動作,當有數據的時候再回來讀取。通常linux網絡API默認都是阻塞的,例如connect、send、recv等。回答后感覺自己心里沒有底,底層的關系到底是什么樣的,比較虛,沒能深入理解。
2、深入理解分析
回來以后,趕緊上網好好查查,加深學習一下。這兩個概念在工作中經常用到這些,例如在linux網絡IO中涉及到如下模型:
(1)阻塞式IO
(2)非阻塞式IO
(3)IO多路復用
(4)信號驅動IO
(5)異步IO
在知乎上面看到一些解釋如下:
截圖如下:
3、總結
同步和異步針對應用程序來,關注的是程序中間的協作關系;阻塞與非阻塞更關注的是單個進程的執行狀態。
同步:執行一個操作之后,等待結果,然后才繼續執行后續的操作。
異步:執行一個操作后,可以去執行其他的操作,然后等待通知再回來執行剛才沒執行完的操作。
阻塞:進程給CPU傳達一個任務之后,一直等待CPU處理完成,然后才執行后面的操作。
非阻塞:進程給CPU傳達任我后,繼續處理后續的操作,隔斷時間再來詢問之前的操作是否完成。這樣的過程其實也叫輪詢。
阻塞、非阻塞、多路IO復用,都是同步IO,異步必定是非阻塞的,所以不存在異步阻塞和異步非阻塞的說法。真正的異步IO需要CPU的深度參與。換句話說,只有用戶線程在操作IO的時候根本不去考慮IO的執行全部都交給CPU去完成,而自己只等待一個完成信號的時候,才是真正的異步IO。所以,拉一個子線程去輪詢、去死循環,或者使用select、poll、epool,都不是異步。
參考網址:
https://www.zhihu.com/question/19732473
https://www.zhihu.com/question/27965282
http://www.smithfox.com/?e=191
文章列表