java - 同步/異步與阻塞/非阻塞之間的差異具體是什么?
問題描述
就我的理解,同步/阻塞是同一概念,都是客戶端等待服務(wù)端的回執(zhí),服務(wù)端不返回回執(zhí),客戶端就不往下走;而異步/非阻塞則是客戶端不等待服務(wù)端的回執(zhí),直接往下走,等到服務(wù)端處理結(jié)束后,在調(diào)用異步回調(diào)函數(shù)通知客戶端。
但具體的,同步和阻塞,異步和非阻塞間的區(qū)別,分不清,有誰能解惑呢?
問題解答
回答1:推薦一篇博文聊聊Linux 五種IO模型,寫的很不錯(cuò)。簡要的跟你說下這幾個(gè)。首先,只有同步才有所謂的阻塞非阻塞,異步并沒有。常規(guī)的錯(cuò)誤理解是,我們覺得異步就是非阻塞的,然而并不是這樣的。這里的同步和異步的區(qū)別就是,對(duì)于一個(gè)網(wǎng)絡(luò)IO或者磁盤IO的“整個(gè)過程”有沒有存在阻塞,是整個(gè)過程。以一次read的系統(tǒng)調(diào)用為例子,作為一個(gè)用戶線程,當(dāng)你發(fā)起一次read的系統(tǒng)調(diào)用的時(shí)候,可以分為兩個(gè)操作,
一是數(shù)據(jù)讀取:把數(shù)據(jù)從磁盤讀到內(nèi)核空間,我們都知道,read屬于系統(tǒng)調(diào)用,用戶級(jí)線程是無法操作的,只能交給內(nèi)核線程去處理,而內(nèi)核線程首先要找到數(shù)據(jù),并讀到內(nèi)核空間中。
二是數(shù)據(jù)復(fù)制:把數(shù)據(jù)從內(nèi)核空間讀取到用戶空間。然后用戶線程才可以使用這些數(shù)據(jù)。
所以簡單的說,
同步就是上述兩個(gè)過程都阻塞了,你用戶線程一直在等。
非阻塞就是上述第一個(gè)過程你沒有阻塞,但是用戶線程必須不斷的詢問os,數(shù)據(jù)是否從磁盤拷貝到內(nèi)和空間了,如果拷貝好了,則在數(shù)據(jù)復(fù)制的過程阻塞。所以所有的同步過程,在第二階段都是阻塞的,盡管這是非阻塞的調(diào)用。
多路復(fù)用:和非阻塞一樣,在第二階段也是阻塞的,但是第一階段不再由自己去詢問操作系統(tǒng),而是統(tǒng)一交給一個(gè)內(nèi)核線程去處理(linux上實(shí)現(xiàn)的有poll,以及改進(jìn)版的epoll),當(dāng)你的數(shù)據(jù)讀取完成,這個(gè)線程就發(fā)送一個(gè)信號(hào)給原先發(fā)起系統(tǒng)調(diào)用的用戶線程,然后用戶線程就進(jìn)入阻塞,并開始數(shù)據(jù)拷貝了。
異步:上述兩個(gè)過程都是非阻塞的。
上述只是簡單描述,希望有幫助
回答2:同步異步的概念主要是描述IO方面的。簡而言之同步和異步的主要區(qū)別是通知調(diào)用進(jìn)程或線程的方式,立即返回通知即同步,通過注冊(cè)回調(diào)通知?jiǎng)t是異步。阻塞和非阻塞主要描述函數(shù)的調(diào)用返回情況。函數(shù)立即返回即非阻塞,函數(shù)被掛起則阻塞。
舉個(gè)簡單類比場景,假如你去餐廳點(diǎn)餐。
同步阻塞你跟訂餐員說要一份臺(tái)灣牛肉面,訂餐員聽見之后就去廚房,過了一會(huì)才拿出來給你。這段時(shí)間你就在前臺(tái)傻傻的等著,沒有任何回復(fù),什么也不做(阻塞),你在下單之后沒有收到任何回復(fù),一直等待的過程就是同步的通信。
同步非阻塞你跟訂餐員說要一份蘭州牛肉面,訂餐員回復(fù)你說,估計(jì)要五分鐘。然后你想了一下,五分鐘可以刷一刷帖子,干點(diǎn)別的事情解悶??墒呛芸於亲羽I,你每隔一分鐘就問一次好了沒,得到的回復(fù)就是還沒好,直到5分鐘后,才拿到面。等待的過程中你沒有閑著,可以干別的事情,這是非阻塞。由于你還是主動(dòng)詢問結(jié)果并等待訂餐員的回復(fù),所以這還是同步的。
異步阻塞與非阻塞所謂異步,就是不需要你主動(dòng)去詢問結(jié)果,而是注冊(cè)一個(gè)回調(diào)函數(shù)。即你點(diǎn)餐完畢之后,訂餐員給了你一個(gè)號(hào)。旁邊有一個(gè)機(jī)器,輪到你的時(shí)候,機(jī)器就會(huì)叫號(hào)。通知你的這個(gè)過程叫異步,如果你在一旁坐著,啥也不干,那么你就是阻塞狀態(tài)。如果在一旁刷網(wǎng)頁,那么就是非阻塞。
所以區(qū)別同步還是異步,主要在于消息的通知方式,阻塞和非阻塞在于函數(shù)調(diào)用等待通知時(shí)的狀態(tài),即是否掛起,以至于當(dāng)前的線程或者進(jìn)程,和還是能否繼續(xù)做別的。
通常還有一種協(xié)程式的方式實(shí)現(xiàn)異步非阻塞。即函數(shù)調(diào)用遇到IO的時(shí)候,注冊(cè)回調(diào)函數(shù)后,就掛起返回,因?yàn)榉祷亓?,所以是非阻塞,然后等IO完成了,回調(diào)函數(shù)通知喚醒掛起的函數(shù),此時(shí)就是異步。
回答3:一般來說阻塞和非阻塞式指IO調(diào)用是立即返回(非阻塞)還是等待完成再返回(阻塞)。同步和異步是個(gè)廣義概念,是阻塞和非阻塞的表現(xiàn)。
回答4:其實(shí)你理解的很對(duì),同步就是指不會(huì)出現(xiàn)數(shù)據(jù)的不統(tǒng)一,單線程是順序執(zhí)行。不同步就是會(huì)出現(xiàn)數(shù)據(jù)不統(tǒng)一的現(xiàn)象,比如多線程的時(shí)候,這個(gè)線程用到的數(shù)據(jù)可能會(huì)被另一個(gè)線程給改了,就造成數(shù)據(jù)不同步了。而阻塞和非阻塞是指在線程運(yùn)行的時(shí)候是否等待函數(shù)返回,如果是單線程就會(huì)一直等待,如果是多線程的就不等待向下執(zhí)行這個(gè)時(shí)候就容易出現(xiàn)不同步的情況了。
相關(guān)文章:
1. 數(shù)據(jù)庫 - MySQL 單表500W+數(shù)據(jù),查詢超時(shí),如何優(yōu)化呢?2. javascript - 百度echarts series數(shù)據(jù)更新問題3. 求大神幫我看看是哪里寫錯(cuò)了 感謝細(xì)心解答4. MySQL客戶端吃掉了SQL注解?5. mac 安裝 python_MySQLdb6. javascript - 圖片能在網(wǎng)站顯示,但控制臺(tái)仍舊報(bào)錯(cuò)403 (Forbidden)7. php自學(xué)從哪里開始?8. mysql - AttributeError: ’module’ object has no attribute ’MatchType’9. python小白的基礎(chǔ)問題 關(guān)于while循環(huán)的嵌套10. phpstady在win10上運(yùn)行
