日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

聊聊同步、异步、阻塞与非阻塞

發(fā)布時(shí)間:2023/11/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 聊聊同步、异步、阻塞与非阻塞 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

近來遇到了一些常見的概念,尤其是網(wǎng)絡(luò)編程方面的概念,如:阻塞、非阻塞、異步I/O等等,對(duì)于這些概念自己也沒有太清晰的認(rèn)識(shí),只是很模糊的概念,說了解吧也了解,但是要讓自己準(zhǔn)確的描述概念方面的具體細(xì)節(jié),卻說的不那么準(zhǔn)確,這也是自己在這幾個(gè)方面也沒有細(xì)細(xì)考究過的原因吧。經(jīng)過看了些這幾個(gè)概念的資料,發(fā)現(xiàn)同步、異步、阻塞、非阻塞的概念其實(shí)也并不難以理解,在此寫下此文,歡迎拍磚,希望多多交流。

1 同步與異步#

首先來解釋同步和異步的概念,這兩個(gè)概念與消息的通知機(jī)制有關(guān)。也就是同步與異步主要是從消息通知機(jī)制角度來說的。

1.1 概念描述##

所謂同步就是一個(gè)任務(wù)的完成需要依賴另外一個(gè)任務(wù)時(shí),只有等待被依賴的任務(wù)完成后,依賴的任務(wù)才能算完成,這是一種可靠的任務(wù)序列。要么成功都成功,失敗都失敗,兩個(gè)任務(wù)的狀態(tài)可以保持一致。

所謂異步是不需要等待被依賴的任務(wù)完成,只是通知被依賴的任務(wù)要完成什么工作,依賴的任務(wù)也立即執(zhí)行,只要自己完成了整個(gè)任務(wù)就算完成了。至于被依賴的任務(wù)最終是否真正完成,依賴它的任務(wù)無法確定,所以它是不可靠的任務(wù)序列。

1.2 消息通知##

異步的概念和同步相對(duì)。當(dāng)一個(gè)同步調(diào)用發(fā)出后,調(diào)用者要一直等待返回消息(結(jié)果)通知后,才能進(jìn)行后續(xù)的執(zhí)行;當(dāng)一個(gè)異步過程調(diào)用發(fā)出后,調(diào)用者不能立刻得到返回消息(結(jié)果)。實(shí)際處理這個(gè)調(diào)用的部件在完成后,通過狀態(tài)、通知和回調(diào)來通知調(diào)用者。

這里提到執(zhí)行部件和調(diào)用者通過三種途徑返回結(jié)果:狀態(tài)、通知和回調(diào)。使用哪一種通知機(jī)制,依賴于執(zhí)行部件的實(shí)現(xiàn),除非執(zhí)行部件提供多種選擇,否則不受調(diào)用者控制。

  • 如果執(zhí)行部件用狀態(tài)來通知,那么調(diào)用者就需要每隔一定時(shí)間檢查一次,效率就很低(有些初學(xué)多線程編程的人,總喜歡用一個(gè)循環(huán)去檢查某個(gè)變量的值,這其實(shí)是一種很嚴(yán)重的錯(cuò)誤);

  • 如果是使用通知的方式,效率則很高,因?yàn)閳?zhí)行部件幾乎不需要做額外的操作。至于回調(diào)函數(shù),其實(shí)和通知沒太多區(qū)別。

  • 1.2 場(chǎng)景比喻##

    舉個(gè)例子,比如我去銀行辦理業(yè)務(wù),可能會(huì)有兩種方式:

  • 選擇排隊(duì)等候;

  • 另種選擇取一個(gè)小紙條上面有我的號(hào)碼,等到排到我這一號(hào)時(shí)由柜臺(tái)的人通知我輪到我去辦理業(yè)務(wù)了;

  • 第一種:前者(排隊(duì)等候)就是同步等待消息通知,也就是我要一直在等待銀行辦理業(yè)務(wù)情況;

    第二種:后者(等待別人通知)就是異步等待消息通知。在異步消息處理中,等待消息通知者(在這個(gè)例子中就是等待辦理業(yè)務(wù)的人)往往注冊(cè)一個(gè)回調(diào)機(jī)制,在所等待的事件被觸發(fā)時(shí)由觸發(fā)機(jī)制(在這里是柜臺(tái)的人)通過某種機(jī)制(在這里是寫在小紙條上的號(hào)碼,喊號(hào))找到等待該事件的人。

    2 阻塞與非阻塞#

    阻塞和非阻塞這兩個(gè)概念與程序(線程)等待消息通知(無所謂同步或者異步)時(shí)的狀態(tài)有關(guān)。也就是說阻塞與非阻塞主要是程序(線程)等待消息通知時(shí)的狀態(tài)角度來說的。

    2.1 概念描述##

    阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起,一直處于等待消息通知,不能夠執(zhí)行其他業(yè)務(wù)。函數(shù)只有在得到結(jié)果之后才會(huì)返回。

    有人也許會(huì)把阻塞調(diào)用和同步調(diào)用等同起來,實(shí)際上它們是不同的。

  • 對(duì)于同步調(diào)用來說,很多時(shí)候當(dāng)前線程可能還是激活的,只是從邏輯上當(dāng)前函數(shù)沒有返回而已,此時(shí),這個(gè)線程可能也會(huì)處理其他的消息。還有一點(diǎn),在這里先擴(kuò)展下:
  • (a) 如果這個(gè)線程在等待當(dāng)前函數(shù)返回時(shí),仍在執(zhí)行其他消息處理,那這種情況就叫做同步非阻塞;

    (b) 如果這個(gè)線程在等待當(dāng)前函數(shù)返回時(shí),沒有執(zhí)行其他消息處理,而是處于掛起等待狀態(tài),那這種情況就叫做同步阻塞;

    所以同步的實(shí)現(xiàn)方式會(huì)有兩種:同步阻塞、同步非阻塞;同理,異步也會(huì)有兩種實(shí)現(xiàn):異步阻塞、異步非阻塞;

  • 對(duì)于阻塞調(diào)用來說,則當(dāng)前線程就會(huì)被掛起等待當(dāng)前函數(shù)返回;
  • 非阻塞和阻塞的概念相對(duì)應(yīng),指在不能立刻得到結(jié)果之前,該函數(shù)不會(huì)阻塞當(dāng)前線程,而會(huì)立刻返回。雖然表面上看非阻塞的方式可以明顯的提高CPU的利用率,但是也帶了另外一種后果就是系統(tǒng)的線程切換增加。增加的CPU執(zhí)行時(shí)間能不能補(bǔ)償系統(tǒng)的切換成本需要好好評(píng)估。

    2.2 場(chǎng)景比喻##

    繼續(xù)上面的那個(gè)例子,不論是排隊(duì)還是使用號(hào)碼等待通知,如果在這個(gè)等待的過程中,等待者除了等待消息通知之外不能做其它的事情,那么該機(jī)制就是阻塞的,表現(xiàn)在程序中,也就是該程序一直阻塞在該函數(shù)調(diào)用處不能繼續(xù)往下執(zhí)行。

    相反,有的人喜歡在銀行辦理這些業(yè)務(wù)的時(shí)候一邊打打電話發(fā)發(fā)短信一邊等待,這樣的狀態(tài)就是非阻塞的,因?yàn)樗?等待者)沒有阻塞在這個(gè)消息通知上,而是一邊做自己的事情一邊等待。

    但是需要注意了,同步非阻塞形式實(shí)際上是效率低下的,想象一下你一邊打著電話一邊還需要抬頭看到底隊(duì)伍排到你了沒有。如果把打電話和觀察排隊(duì)的位置看成是程序的兩個(gè)操作的話,這個(gè)程序需要在這兩種不同的行為之間來回的切換,效率可想而知是低下的;而異步非阻塞形式卻沒有這樣的問題,因?yàn)榇螂娫捠悄?等待者)的事情,而通知你則是柜臺(tái)(消息觸發(fā)機(jī)制)的事情,程序沒有在兩種不同的操作中來回切換。

    3 同步/異步與阻塞/非阻塞#

  • 同步阻塞形式
  • 效率是最低的,

    拿上面的例子來說,就是你專心排隊(duì),什么別的事都不做。

    實(shí)際程序中:就是未對(duì)fd 設(shè)置O_NONBLOCK標(biāo)志位的read/write 操作;

  • 異步阻塞形式
  • 如果在銀行等待辦理業(yè)務(wù)的人采用的是異步的方式去等待消息被觸發(fā)(通知),也就是領(lǐng)了一張小紙條,假如在這段時(shí)間里他不能離開銀行做其它的事情,那么很顯然,這個(gè)人被阻塞在了這個(gè)等待的操作上面;

    異步操作是可以被阻塞住的,只不過它不是在處理消息時(shí)阻塞,而是在等待消息通知時(shí)被阻塞。

    比如select 函數(shù),假如傳入的最后一個(gè)timeout參數(shù)為NULL,那么如果所關(guān)注的事件沒有一個(gè)被觸發(fā),程序就會(huì)一直阻塞在這個(gè)select 調(diào)用處。

  • 同步非阻塞形式
  • 實(shí)際上是效率低下的,

    想象一下你一邊打著電話一邊還需要抬頭看到底隊(duì)伍排到你了沒有,如果把打電話和觀察排隊(duì)的位置看成是程序的兩個(gè)操作的話,這個(gè)程序需要在這兩種不同的行為之間來回的切換,效率可想而知是低下的。

    很多人會(huì)寫阻塞的read/write 操作,但是別忘了可以對(duì)fd設(shè)置O_NONBLOCK 標(biāo)志位,這樣就可以將同步操作變成非阻塞的了。

  • 異步非阻塞形式
  • 效率更高,

    因?yàn)榇螂娫捠悄?等待者)的事情,而通知你則是柜臺(tái)(消息觸發(fā)機(jī)制)的事情,程序沒有在兩種不同的操作中來回切換。

    比如說,這個(gè)人突然發(fā)覺自己煙癮犯了,需要出去抽根煙,于是他告訴大堂經(jīng)理說,排到我這個(gè)號(hào)碼的時(shí)候麻煩到外面通知我一下(注冊(cè)一個(gè)回調(diào)函數(shù)),那么他就沒有被阻塞在這個(gè)等待的操作上面,自然這個(gè)就是異步+非阻塞的方式了。

    如果使用異步非阻塞的情況,比如aio_*組的操作,當(dāng)發(fā)起一個(gè)aio_read操作時(shí),函數(shù)會(huì)馬上返回不會(huì)被阻塞,當(dāng)所關(guān)注的事件被觸發(fā)時(shí)會(huì)調(diào)用之前注冊(cè)的回調(diào)函數(shù)進(jìn)行處理。

    很多人會(huì)把同步和阻塞混淆,我想是因?yàn)楹芏鄷r(shí)候同步操作會(huì)以阻塞的形式表現(xiàn)出來,比如很多人會(huì)寫阻塞的read/write操作,但是別忘了可以對(duì)fd設(shè)置O_NONBLOCK標(biāo)志位,這樣就可以將同步操作變成非阻塞的了。但最根本是因?yàn)闆]有區(qū)分這兩個(gè)概念,比如阻塞的read/write操作中,其實(shí)是把消息通知機(jī)制和等待消息通知的狀態(tài)結(jié)合在了一起,在這里所關(guān)注的消息就是fd是否可讀/寫,而等待消息通知的狀態(tài)則是對(duì)fd可讀/寫等待過程中程序(線程)的狀態(tài)。當(dāng)我們將這個(gè)fd設(shè)置為非阻塞的時(shí)候,read/write操作就不會(huì)在等待消息通知這里阻塞,如果fd不可讀/寫則操作立即返回。

    同樣的,很多人也會(huì)把異步和非阻塞混淆,因?yàn)楫惒讲僮饕话愣疾粫?huì)在真正的IO操作處被阻塞,比如如果用select函數(shù),當(dāng)select返回可讀時(shí)再去read一般都不會(huì)被阻塞,而是在select函數(shù)調(diào)用處阻塞。

    4 小明的故事#

    對(duì)上面所講的概念再次進(jìn)行一個(gè)場(chǎng)景梳理,上面已經(jīng)明確說明,同步/異步關(guān)注的是消息通知的機(jī)制,而阻塞/非阻塞關(guān)注的是程序(線程)等待消息通知時(shí)的狀態(tài)。以小明下載文件打個(gè)比方,從這兩個(gè)關(guān)注點(diǎn)來再次說明這兩組概念,希望能夠更好的促進(jìn)大家的理解。

  • 同步阻塞:小明一直盯著下載進(jìn)度條,到 100% 的時(shí)候就完成。
  • 同步體現(xiàn)在:等待下載完成通知;

    阻塞體現(xiàn)在:等待下載完成通知過程中,不能做其他任務(wù)處理;

  • 同步非阻塞:小明提交下載任務(wù)后就去干別的,每過一段時(shí)間就去瞄一眼進(jìn)度條,看到 100% 就完成。
  • 同步體現(xiàn)在:等待下載完成通知;

    非阻塞體現(xiàn)在:等待下載完成通知過程中,去干別的任務(wù)了,只是時(shí)不時(shí)會(huì)瞄一眼進(jìn)度條;【小明必須要在兩個(gè)任務(wù)間切換,關(guān)注下載進(jìn)度】

  • 異步阻塞:小明換了個(gè)有下載完成通知功能的軟件,下載完成就“叮”一聲。不過小明仍然一直等待“叮”的聲音(看起來很傻,不是嗎)。
  • 異步體現(xiàn)在:下載完成“叮”一聲通知;

    阻塞體現(xiàn)在:等待下載完成“叮”一聲通知過程中,不能做其他任務(wù)處理;

  • 異步非阻塞:仍然是那個(gè)會(huì)“叮”一聲的下載軟件,小明提交下載任務(wù)后就去干別的,聽到“叮”的一聲就知道完成了。
  • 異步體現(xiàn)在:下載完成“叮”一聲通知;

    非阻塞體現(xiàn)在:等待下載完成“叮”一聲通知過程中,去干別的任務(wù)了,只需要接收“叮”聲通知即可;【軟件處理下載任務(wù),小明處理其他任務(wù),不需關(guān)注進(jìn)度,只需接收軟件“叮”聲通知,即可】

    也就是說,同步/異步是“下載完成消息”通知的方式(機(jī)制),而阻塞/非阻塞則是在等待“下載完成消息”通知過程中的狀態(tài)(能不能干其他任務(wù)),在不同的場(chǎng)景下,同步/異步、阻塞/非阻塞的四種組合都有應(yīng)用。

    所以,綜上所述,同步和異步僅僅是關(guān)注的消息如何通知的機(jī)制,而阻塞與非阻塞關(guān)注的是等待消息通知時(shí)的狀態(tài)。也就是說,同步的情況下,是由處理消息者自己去等待消息是否被觸發(fā),而異步的情況下是由觸發(fā)機(jī)制來通知處理消息者,所以在異步機(jī)制中,處理消息者和觸發(fā)機(jī)制之間就需要一個(gè)連接的橋梁:

    在銀行的例子中,這個(gè)橋梁就是小紙條上面的號(hào)碼。

    在小明的例子中,這個(gè)橋梁就是軟件“叮”的聲音。

    最后,請(qǐng)大家注意理解“消息通知機(jī)制”和“等待消息通知時(shí)的狀態(tài)”這兩個(gè)概念,這是理解四個(gè)概念的關(guān)鍵所在。



    作者:猿碼道
    鏈接:https://www.jianshu.com/p/aed6067eeac9
    來源:簡(jiǎn)書
    簡(jiǎn)書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。

    總結(jié)

    以上是生活随笔為你收集整理的聊聊同步、异步、阻塞与非阻塞的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。