摘要:接下來我們就來探討下異步同步與阻塞非阻塞它們其中的區(qū)別。阻塞非阻塞是針對的第一階段的描述。
一: 引言Author: bugall
Wechat: bugallF
Email: 769088641@qq.com
Github: https://github.com/bugall
在面試中我們會碰到這種場景:
面試官:能解釋下什么是同步,異步么?
程序員:假如我們執(zhí)行A,B兩個IO操作的時候,如果必須等待A完成后才能執(zhí)行B那么這個就是
同步的,如果A,B可以同時執(zhí)行那么就是異步的。
面試官:那能解釋下什么是阻塞什么是非阻塞么?
程序員:如果必須等待A完成后才能執(zhí)行B那么這個就是阻塞的,如果A,B可以同時執(zhí)行那么就 是非阻塞的
面試官:那你的意思異步/同步的概念與阻塞非阻塞一樣了?
程序員:嗄。。。可以這么說吧。我覺得可以并發(fā)執(zhí)行的就是異步非阻塞的。one by one執(zhí)行 的就是同步阻塞的
二:區(qū)分每個人看去看同一個問題都會有不同的理解,原因就是因為每個人的看待問題的深度不一樣,就像上面的對白,程
序員的理解只是停留在應用層面,代碼里有多個IO操作,每個IO操作都可以不用互相等待的“同時”執(zhí)行。
接下來我們就來探討下異步/同步與阻塞/非阻塞它們其中的區(qū)別。
阻塞 / 非阻塞描述的是函數(shù), 指訪問某個函數(shù)時是否會阻塞線程(block),導致線程進入阻塞狀態(tài)。
同步 / 異步描述的是執(zhí)行IO操作的主體是誰,同步是由用戶態(tài)的進程自己去執(zhí)行IO操作,異步是用戶態(tài)進程不關心IO細節(jié),由內(nèi)核態(tài)進程去完成IO操作然后通知用戶態(tài)進程。
好的,現(xiàn)在定義已經(jīng)描述完了。現(xiàn)在可以區(qū)分它們之間的區(qū)別了么?(吃瓜群眾:這TM的寫的是什么?) ,別急,我們下面舉栗說明,包教包會。
三:舉栗一般來說IO分為兩個階段,第一階段是等待數(shù)據(jù)階段,第二階段是內(nèi)核空間的數(shù)據(jù)拷貝到用戶空間,假設一個線程(或是進程)P準備執(zhí)行一個IO操作的話它會經(jīng)歷以下過程:
第一階段:
P發(fā)出一個IO請求,這時候會有兩種情況: 1:立刻返回: 非阻塞 2:一直等待,P調(diào)用sleep/wait休眠或是掛起,讓出CPU給別的線程/進程 阻塞
第二階段:
這時內(nèi)核的數(shù)據(jù)終于準備好了, 那么現(xiàn)在用戶進程想要讀取內(nèi)核空間的數(shù)據(jù)有兩種方式: 1: P自己把數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間 同步 2:P創(chuàng)建一個線程做數(shù)據(jù)copy的工作 異步
現(xiàn)在應該明白了吧。阻塞/非阻塞是針對IO的第一階段的描述。異步/同步是針對IO的第二階段的描述也就是IO的主體。
這里主要比較難理解的就是同步/異步。首先P在發(fā)起IO的請求的時候如果P本身還要負責IO請求后的數(shù)據(jù)copy(內(nèi)核空間到用戶空間)工作。那么我們就可以說是同步的。
如果P在發(fā)起IO操作后數(shù)據(jù)copy的工作由內(nèi)核線程/進程或是P自己再創(chuàng)建一個線程/進程去完成,那么我們就可以稱之為異步
四:排列組合同步阻塞IO:
同一個線程在操作IO時一直阻塞,直到讀取數(shù)據(jù)成功,然后線程本身負責把數(shù)據(jù)從核心空間拷貝到用戶空間
同步非阻塞:
同一個線程發(fā)起IO后,立即獲得返回,后面定期輪詢數(shù)據(jù)讀取情況,發(fā)現(xiàn)數(shù)據(jù)讀取成功,線程本身負責把數(shù)據(jù)從核心空間拷貝到用戶空間
異步非阻塞:
一個線程發(fā)起IO后,立即返回,由另外的線程發(fā)現(xiàn)數(shù)據(jù)讀取成功,把數(shù)據(jù)從核心空間拷貝到用戶空間。
非阻塞同步IO由于讀寫方法非阻塞,并且需要用戶自己來進行讀寫,所以每次調(diào)用讀寫方法實際讀寫的字節(jié)數(shù)是不確定的,所以需要一個Buffer來保存每次讀寫的字節(jié)狀態(tài)。更重要的是用戶不知道什么時候完成了讀寫,一般需要用
while循環(huán)判斷Buffer的狀態(tài)來跟蹤讀寫。非阻塞異步IO由于是內(nèi)核線程進行讀寫,并且在IO完成后會回調(diào)用戶提供的callback,編程模型就比較簡單,用戶只需要調(diào)用讀寫,提供回調(diào)就可以了,比如 read(filename, callback)select / poll / epoll 從本質(zhì)上說都是非阻塞同步IO,select會收到IO就緒的狀態(tài),然后通知用戶去處理
IO,實際的IO操作還需要用戶等待內(nèi)核復制操作。
要理解IO就緒和完成的區(qū)別。就緒指的是還需要用戶自己去處理,完成指的是內(nèi)核幫助完成了,用戶不用關心IO過
程,只需要提供回調(diào)函數(shù)。
五:并行/并發(fā)與異步 并行對多處理器而言--多個程序在同一時刻發(fā)生,具有并發(fā)的含義,但并發(fā)不一定并行,也亦是說并發(fā)事件之間不一定要同一時刻發(fā)生。
并行:在單處理器中多道程序設計系統(tǒng)中,進程被交替執(zhí)行,表現(xiàn)出一種并發(fā)的外部特種;在多處理器系統(tǒng)中,進
程不僅可以交替執(zhí)行,而且可以重疊執(zhí)行。在多處理器上的程序才可實現(xiàn)并行處理。計算機操作系統(tǒng)中把并行性和并發(fā)性明顯區(qū)分開,主要是從微觀的角度來說的,具體是指進程的并行性(多處理機的情況下,多個進程同時運行)和并發(fā)性(單處理機的情況下,多個進程在同一時間間隔運行的)
對單處理器而言--多個程序在同一時間段發(fā)生;
并發(fā)中又有:互斥和同步:
互斥:進程間相互排斥使用臨界資源;比如寫操作; 同步:不是排斥關系而是依賴關系,前一個進程的輸出是后一個進程的輸入 當?shù)谝粋€進程沒有結(jié)束時第二個進程必須等待,相互協(xié)同完成一些事情; 具有同步關系的一組進程并發(fā)時發(fā)送的消息稱為消息或者事件;
同步和異步:
異步:就是線程B在等待A的結(jié)果的時候還可以繼續(xù)干自己的事兒, 之間通過消息和事件來通知對方,提高了程序運行的效率。 簡而言之,就是不是站在那兒傻傻死等;異步和多線程并不是一回事, 異步是最終目的,多線程只是實現(xiàn)的一種方法。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/83101.html
摘要:一閱前熱身為了更加形象的說明同步異步阻塞非阻塞,我們以小明去買奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應結(jié)果發(fā)給相應的連接請求處理完成因為基于,所以每個可以處理無數(shù)個連接請求。如此,就輕松的處理了高并發(fā)。 一、閱前熱身 為了更加形象的說明同步異步、阻塞非阻塞,我們以小明去買奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點在消息通知的方式上...
摘要:一閱前熱身為了更加形象的說明同步異步阻塞非阻塞,我們以小明去買奶茶為例。等奶茶做好了,店員喊一聲小明,奶茶好了,然后小明去取奶茶。將響應結(jié)果發(fā)給相應的連接請求處理完成因為基于,所以每個可以處理無數(shù)個連接請求。如此,就輕松的處理了高并發(fā)。 一、閱前熱身 為了更加形象的說明同步異步、阻塞非阻塞,我們以小明去買奶茶為例。 1、同步與異步 ①同步與異步的理解 同步與異步的重點在消息通知的方式上...
摘要:而是在調(diào)用發(fā)出后,被調(diào)用者通過狀態(tài)通知來通知調(diào)用者,或通過回調(diào)函數(shù)處理這個調(diào)用。請求程序發(fā)出請求,從服務器端獲取數(shù)據(jù),并設置了回調(diào)函數(shù)。然后,瀏覽器會設置偵聽來自網(wǎng)絡的響應,拿到數(shù)據(jù)后,將該回調(diào)函數(shù)插入到事件循環(huán)。 并發(fā)與并行 并發(fā)是指兩個或多個事件鏈隨時間發(fā)展交替執(zhí)行,以至于從更高的層次來看,就像是同時運行(但在任意時刻只處理一個事件) 并發(fā)的關鍵是你有處理多個任務的能力,不一定同...
摘要:原文地址要想更好了解編程,有一個不可繞過的環(huán)節(jié)就是在中,一切皆文件實際上要文件干啥不就是讀寫么所以,這句話本質(zhì)就是才是王道用的打開文件關閉文件讀讀寫寫,這叫本地文件在編程中,本質(zhì)就是網(wǎng)絡所以,在開始進一步的編程前,我們必須先從概念上認識好 [原文地址:https://blog.ti-node.com/blog...] 要想更好了解socket編程,有一個不可繞過的環(huán)節(jié)就是IO.在Lin...
摘要:異步本質(zhì)上應該就是多線程語言的產(chǎn)物。如果是多線程的異步,假死的應該是運行方法的線程,而方法仍然會按預期打印出。當然了,按我個人的理解,應該說是是的回調(diào)函數(shù)。 引子 每個故事都有由來。前兩天在看 gulp 的時候,看到了它有個 promise 的玩意兒,然后的然后,這兩天就掉進了 javascript 的異步和回調(diào)的坑里面去了。 其間搜索了 javascript promise,看到了...
閱讀 2943·2023-04-25 19:20
閱讀 786·2021-11-24 09:38
閱讀 2040·2021-09-26 09:55
閱讀 2430·2021-09-02 15:11
閱讀 2015·2019-08-30 15:55
閱讀 3610·2019-08-30 15:54
閱讀 3148·2019-08-30 14:03
閱讀 2962·2019-08-29 17:11