最近生產系統出現了異常,在大數據量socket交互時,服務器端報文接受不完整。 解決過程發現自己對很多概念不是很理解,需要加強一下。
實戰派的解釋:
比如我去銀行辦理業務,可能選擇排隊等候,也可能取一個小紙條上面有我的號碼,等到排到我這一號時由柜臺的人通知我輪到我去辦理業務了.
前者(排隊等候)就是同步等待消息,而后者(等待別人通知)就是異步等待消息.在異步消息處理中,等待消息者(在這個例子中就是等待辦理業務的人)往往注冊一個回調機制,在所等待的事件被觸發時由觸發機制(在這里是柜臺的人)通過某種機制(在這里是寫在小紙條上的號碼)找到等待該事件的人.
而在實際的程序中,同步消息處理就好比簡單的read/write操作,它們需要等待這兩個操作成功才能返回;而異步處理機制就是類似于 select/poll 之類的多路復用IO操作,當所關注的消息被觸發時,由消息觸發機制通知觸發對消息的處理.
其次再來解釋一下阻塞和非阻塞,這兩個概念與程序等待消息(無所謂同步或者異步)時的狀態有關.
繼續上面的那個例子,不論是排隊還是使用號碼等待通知,如果在這個等待的過程中,等待者除了等待消息之外不能做其它的事情,那么該機制就是阻塞的,表現在程序中,也就是該程序一直阻塞在該函數調用處不能繼續往下執行.相反,有的人喜歡在銀行辦理這些業務的時候一邊打打電話發發短信一邊等待,這樣的狀態就是非阻塞的,因為他(等待者)沒有阻塞在這個消息通知上,而是一邊做自己的事情一邊等待.但是需要注意了,第一種同步非阻塞形式實際上是效率低下的,想象一下你一邊打著電話一邊還需要抬頭看到底隊伍排到你了沒有,如果把打電話和觀察排隊的位置看成是程序的兩個操作的話,這個程序需要在這兩種不同的行為之間來回的切換,效率可想而知是低下的;而后者,異步非阻塞形式卻沒有這樣的問題,因為打電話是你(等待者)的事情,而通知你則是柜臺(消息觸發機制)的事情,程序沒有在兩種不同的操作中來回切換.學術派的解釋:
AIO is "asynchronous I/O", i.e., the operation is invoked asynchronously and control returns to the client while the OS kernel processes the I/O request. When the operation completes there is some mechanism for the client to retrieve the results.
Non-blocking I/O tries an operation (such as a read() or write()) and if it the operation would block (e.g., due to flow control on a TCP connection or due to lack of data in a socket), the call returns -1 and sets errno to EWOULDBLOCK
翻譯如下:
異步IO: 操作被異步調用時,控制權交給客戶端,I/O操作請求則交由操作系統內核處理,當操作完成后,通過某種機制將結果通知客戶端。
非阻塞I/O:嘗試調用某操作,如果操作被阻塞,則調用返回-1并置錯誤值為EWOULDBLOCK。
二者的區別在于,阻塞/非阻塞是表現,同步/異步是原因,我們說某某操作是阻塞起的,或者某某線程是阻塞起的,是因為在等待操作結果的同步返回;我們說某某操作是非阻塞的,是因為操作結果會通過異步方式返回