同步:線程自己去獲取結果。(一個線程)
異步:線程自己不去獲取結果,而由其他線程送結果。(至少兩個線程)
異步執行如下圖所示,除非不需要知道結果,否則一般會有一個回調方法。
IO多路複用的本質
為了徹底理解IO多路複用是同步還是異步,咱們探究一下IO多路複用的本質。
I/O多路複用,複用的IO監聽等待這條路。實際上就是用select/poll/epoll監聽多個io對象,當io對象有變化(有數據)的時候就通知用戶進程。好處就是單個進程可以處理多個socket。
select/poll/epoll的優勢并不是對于單個連接能處理得更快,而是在于能處理更多的連接。
對于每一個socket,一般都設置成為non-blocking,但是,整個用戶的process其實是一直被阻塞的。隻不過process是被select這個函數阻塞,而不是被socket IO給阻塞。
I/O多路複用的流程如上圖所示:
(1)當用戶進程調用了select,那麼整個進程會被阻塞;
(2)而同時,内核會“監視”所有select負責的socket;
(3)當任何一個socket中的數據準備好了,select就會返回;
(4)這個時候用戶進程再調用read/accept/write操作,做一些數據從内核拷貝到用戶進程這樣的事情。
所以,I/O 多路複用的特點是通過一種機制一個進程能同時等待多個文件描述符,而這些 文件描述符 (套接字描述符)其中的任意一個進入讀就緒狀态,select()函數就可以返回。
事實上,I/O 多路複用有時候性能比同步阻塞IO還更差一些。因為這裡需要使用兩個系統調用(select 和 recvfrom),而同步阻塞IO隻調用了一個系統調用(recvfrom)。但是,用select的優勢在于它可以同時處理多個連接。所以,如果處理的連接數不是很高的話,可能延遲還更大。
總結打個比方:行軍打仗講究糧草先行。諸葛亮比較牛,他打仗隻帶少量糧草,其他靠敵軍送。這天他又派了暗探去查看敵軍糧草的守衛情況。如果敵人守備松懈,則趁機偷糧。如果這個暗探隻偷一袋糧食,那效率最高的是不是他看到敵軍守備松懈就直接進去偷糧(同步阻塞IO)?但是他要偷的是十萬大軍的糧食,那他就要先回去彙報一聲:“守備松懈啦”。然後百人小分隊一起去把糧草偷出來(I/O 多路複用)。當然啦,以諸葛亮的一貫作風而言,最後他還得放一把火。
暗探在同步阻塞模式下,打探敵情也是他,偷糧也是他。在諸葛亮團隊中,暗探在打探敵情時最終暗探是第一個獲取到結果的。暗探在偷糧時也是第一個自己知道結果的。(同步)
暗探在I/O 多路複用模式下,打探敵情也是他,偷糧是百人小分隊。在諸葛亮團隊中,暗探在打探敵情時最終執行者暗探是第一個獲取到結果的。百人小分隊在偷糧時也是百人小分隊自己先知道結果的。(同步)
綜上,IO多路複用是同步的。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!