剛開(kāi)始接觸網(wǎng)絡(luò)編程的時(shí)候?qū)σ恍┏R?jiàn)的概念常常混淆,究其原因還是沒(méi)有能夠真正理解。隨著實(shí)踐加深,對(duì)概念理解也相對(duì)深一點(diǎn),所以把那些比較容易混淆的概念總結(jié)一下,希望能夠幫助到那些像我之前那樣有同樣疑問(wèn)的朋友。
1.阻塞與非阻塞
阻塞與非阻塞這對(duì)概念應(yīng)該較容易理解,阻塞就是在調(diào)用某些函數(shù)的時(shí)候不會(huì)立即返回,非阻塞就是函數(shù)立即返回,但是用戶所要進(jìn)行的操作可能并沒(méi)有立即完成。
相信大家在剛學(xué)習(xí)網(wǎng)絡(luò)編程的時(shí)候所編寫的小程序基本上都是同步阻塞的形式。阻塞顧名思義就是在進(jìn)行某些操作的時(shí)候卡住了,這里所謂的卡其實(shí)就是用戶調(diào)用一些API,比如srecv的時(shí)候,并不會(huì)立即就返回,而是過(guò)了一會(huì)才返回,是因?yàn)橄到y(tǒng)內(nèi)部在進(jìn)行一些操作,比如以阻塞的形式調(diào)用recv時(shí),其實(shí)系統(tǒng)內(nèi)部就是檢查數(shù)據(jù)接收緩沖區(qū)是否有數(shù)據(jù),如果有就立即讀取并返回,沒(méi)有就一直等待到緩沖區(qū)有數(shù)據(jù)為止,這個(gè)過(guò)程中用戶是不能做其他事情的,這就是阻塞。同樣對(duì)于非阻塞就是在調(diào)用recv的時(shí)候函數(shù)會(huì)立即返回,這個(gè)時(shí)候可能用戶并沒(méi)有讀到任何數(shù)據(jù),有兩種形式去檢查recv是否讀取到數(shù)據(jù),一種是用戶通過(guò)一個(gè)循環(huán)一直循環(huán)檢查recv返回的值是否大于0,這種方式就是同步非阻塞,另一種就是系統(tǒng)在數(shù)據(jù)接收緩沖區(qū)有數(shù)據(jù)后將數(shù)據(jù)寫入用戶緩沖區(qū)然后通過(guò)某種形式通知用戶,這種方式就是異步非阻塞。JAVA中有兩種IO形式,一種是BIO,另一種是NIO,其實(shí)也就是阻塞IO與非阻塞IO兩種形式,相信熟悉JAVA的同學(xué)肯定不陌生。
2.同步與異步
在解釋阻塞與非阻塞的sho已經(jīng)提到了異步與同步的區(qū)別。往往在同步阻塞模式下我們并不能很好地區(qū)分同步與阻塞的區(qū)別。同步異步區(qū)別在于等待消息通知方式上的差別。與阻塞非阻塞是兩種不同的概念,我理解是這是一種被動(dòng)與主動(dòng)的區(qū)別,同步是用戶主動(dòng)去查詢某個(gè)狀態(tài),而異步屬于被動(dòng)的接受系統(tǒng)完成操作通知的一種形式。所以這里也可以看出想要達(dá)到真正的一步是需要操作系統(tǒng)來(lái)支持的。
3.Reactor模式與Proacto模式
Reactor與Proactor應(yīng)該是大家在網(wǎng)絡(luò)編程過(guò)程中總結(jié)出來(lái)的兩種形式罷了。在多路復(fù)用IO網(wǎng)絡(luò)模型編程的時(shí)候經(jīng)常需要進(jìn)行事件分發(fā),所以會(huì)有一個(gè)事件分離器,Reactor與Proactor其實(shí)就是對(duì)應(yīng)不同類型的事件分離器。Reactor主要是講讀寫事件分發(fā)到已注冊(cè)的工作者中,有工作線程負(fù)責(zé)讀取或?qū)懭耄鳳roactor則是由操作系統(tǒng)進(jìn)行相應(yīng)的讀寫操作,然后通知工作線程進(jìn)行下一步動(dòng)作。所以說(shuō)Reactor采用的是同步模式,Proactor采用的是異步模式。
Reactor主要是
4.目前的網(wǎng)絡(luò)模型哪些是真正的異步
目前主要的網(wǎng)絡(luò)編程模型主要有select,epoll,poll,kqueue,IOCP等,另外還有一些開(kāi)源庫(kù),比如Libevent,libuv,libev等,還有比較龐大的ACE其實(shí)都是對(duì)以上幾種模型的一種封裝的形式。真正意義上的異步應(yīng)該就是windows系統(tǒng)提供的IOCP模型,Linux下的epoll通常會(huì)有人會(huì)認(rèn)為是異步網(wǎng)絡(luò)模型,其實(shí)不然,epoll還是需要用戶通過(guò)循環(huán)不斷去檢查文件狀態(tài)的,所以嚴(yán)格來(lái)說(shuō)是一種同步的形式。目前有不少網(wǎng)絡(luò)開(kāi)源第三方庫(kù)通過(guò)模擬的形式提供linux下的異步網(wǎng)絡(luò)模型,其實(shí)基本上都是通過(guò)在某個(gè)線程中將數(shù)據(jù)接收完成再通知另一個(gè)工作線程來(lái)讀取數(shù)據(jù)。真正的異步模型是需要操作系統(tǒng)支持的,Windows提供了這種支持,Linux目前還沒(méi)有,不過(guò)Linux下的epoll模型在有大量連接到情況下性能也是很強(qiáng)的。