您當前的位置:首頁 > 攝影

以下關於非同步的一些理解對嗎?

作者:由 子者陽生之初 發表于 攝影時間:2021-04-29

以下關於非同步的一些理解對嗎?餘騰靖2021-04-29 11:44:03

可以提高 cpu 的利用率,像 java 這種多執行緒語言如果不開多執行緒發個 http 請求主執行緒就一直卡在等待響應了,cpu 一直 pedding 啥也不幹,非同步就不一樣了,發個請求完直接去任務佇列繼續拿任務執行

並行和併發是有區別的,多個 cpu 同時執行不同的任務叫並行,單核多工排程實現宏觀上的並行也叫併發,並行屬於併發,概念上併發更大。非同步當然就是併發,非同步一般指的就是單執行緒,可以讓 io 並行。單核多執行緒是併發而不是並行。

像 JavaScript 這種支援非同步的語言,它的直譯器本身是多程序多執行緒的,程式碼執行到添加回調的地方就把回撥函式交給另一個管非同步任務的執行緒,主執行緒程式碼跑完了就和這個管任務佇列的通訊,把任務拿過來跑。很多語言的非同步本身就是用幾個執行緒排程實現的,甚至於有些非同步就是用執行緒池模擬的。

前面的看懂了這個就不用回答了

有可能出現這種情況,非同步一般就是單執行緒環境下用的,但是這種 bug 是可以透過程式碼來規避的,例如讓非同步任務序列執行,不是說有非同步就一定要非同步,有些東西天生就是需要同步的,比如登入後再去拉使用者資料,登入介面和拉使用者資料的介面都是非同步的,但是你沒登入拿到 token 就去取資料肯定是 401

我對協程不太瞭解,但我感覺協程就是實現非同步的手段

非同步的本質就是透過排程來讓 io 非阻塞,提高單核利用率,好處就是不像多執行緒那樣用鎖來處理耗時任務吧,多執行緒環境下需要開新執行緒大多數情況不就是處理 io,非同步也能讓 io 任務併發,但是非同步的方式可以直接閉包訪問主執行緒程式碼,多執行緒就麻煩了,要執行緒間通訊。

而且在高併發的情況下,比如同時發 10000 個請求,多執行緒也就是 10000 個之間的切換開銷是比較大的,而單執行緒非同步(虛擬機器可能也就是幾個執行緒在排程)。

缺點還是單執行緒一旦被耗時計算卡住了後面的任務就都卡住了,所以耗時計算任務可以考慮多執行緒,但是單核環境下開多執行緒不一定就比單核單執行緒非同步快多少。

以下關於非同步的一些理解對嗎?請問你要賣慘麼2021-04-29 11:49:12

我自己的使用感受就是,非同步是一種程式設計方式

非同步相對於同步而存在

非同步的實現方式一定程度上依賴並行的實現

但實際上並行程式設計的思路更像是把一個任務拆分成幾個小的去透過執行緒的方式加速執行,比如我需要計算 1+2+3+4+5+6

並行的方式是

1+2 = 3

3+4 = 7

5+6 = 11

3+7+11= 21

非同步是針對同步而存在的

他的應用場景自然是針對同步不適用的場景,比如網路資料處理,UI更新

UI更新如果放在主流程上,那麼我們的程式碼將時時刻刻阻塞住UI的更新,這不現實

如果你的程式碼需要給出的程式碼數值進行操作才能執行,那就是不非同步的使用場景

比如讀取檔案,那程式下一步必須用這個資料,不能做其他任何事情,那就不是用非同步的地方

非同步程式設計的核心需求就是不能對主流程進行阻塞

就以tcp的同時讀寫為例,用的就是非同步的概念啊,一個簡單的例子就是如果接收到傳送資訊就是現在介面上,這個就是透過執行緒實現的非同步啊,後臺執行了一個讀執行緒,前臺的主執行緒是傳送的,後臺接收到訊息後,會透過傳入的回撥 的方式進行一個響應。再透過UI的非同步更新執行緒更新到UI上,主執行緒的核心業務始終是傳送

非同步使用在很多interactive程式設計地方

js裡面尤其常用

非同步的實現方式比較多吧,基於協程,執行緒都可以開發非同步程式,也有其他的方式

非同步的核心概念還是 將需要等待操作放置到後臺執行

非同步操作在程式碼中更多的是是一種響應式的操作

當然執行的過程一定是與主流程併發執行

以下關於非同步的一些理解對嗎?知乎使用者tteISz2021-05-05 19:03:23

因為非同步本身就是一個很模糊的概念。

不同程式設計領域中,非同步的意思都不相同。

甚至有些領域中,非同步是非阻塞的意思,例如libmysqlclient的async api。

類似的,還有std::async,這個就是純粹開一個執行緒幹活。

而在一般的網路程式設計中,非同步模型一般是依賴於epoll,iocp這樣的api,封裝出一套針對IO操作的非阻塞的事件回撥介面。

我覺得這樣子去理解非同步會更好一些:一件事情不必做完(這件事情也可以交給別人做),就可以做下一件事情,

就像你工作的時候一樣,寫幾行程式碼,摸一會魚,再寫一會程式碼,再摸一會魚,再上個廁所。。。這也是一種非同步。而同步的做法就是,先摸魚,再寫程式碼,再上廁所。。。所以非同步也未必能提高效率。

至於協程在網路程式設計中的應用,在沒有協程之前,編寫非同步程式需要寫很多回調函式,使得業務邏輯支離破碎,協程僅僅是解決這個回撥地獄的問題,使得程式碼看起來像同步而已,本質的執行邏輯和非同步回撥並沒有區別,所以你在協程內阻塞,就相當於非同步網路程式設計中產生阻塞,本就不應該這麼做。

以下關於非同步的一些理解對嗎?小破孩不會程式設計序2021-05-08 22:31:39

1。非同步後如果還是丟給了自己(自己的CPU,或者自己的機器),業務最終還是由自己來做,那麼同步和非同步都是自己來做,如何能提升執行效率?這樣做沒什麼意義!往往非同步是丟給另一些機器上的服務,而不是自己來做。自己負責主流程,別的機器上的服務幫助自己解決IO耗時內容,那單看自己機器上的服務效率是不是提升了?

2。非同步的意義確實是為了多個獨立任務可以並行處理。

3。回撥函式可以理解為應用層做了一個“上下文”的環境儲存。非同步的場景:1。多個獨立任務,可以透過非同步的方式丟給多臺機器上的服務來執行;2。當前的主流程,不依賴該任務的執行結果,可以選擇非同步執行,從而讓主流程快速返回結果。3。主流程需要開始處理,不能接受阻塞,那麼將可能阻塞的任務拆分出來。

4。非同步用在耗時的地方,那麼可能存在CPU密集任務和IO密集任務。

5短暫的資料不一致,本質不是非同步引起的,而是存在對同一資料的併發讀寫。即使你同步操作,也會存在5中示例的結果。

6。非同步使用者態就可以實現,比如說“協程”,就是語言層面對非同步回撥的一種實現。

以下關於非同步的一些理解對嗎?知乎使用者2022-01-26 00:17:41

非同步(asynchronous)、並行(parallel)、併發(concurrent)、回撥(callback)、事件(event)是五個完全不同概念。英語比較清楚,因五個字長不一樣,所以我喜歡說“平行”,而非“並行”。我剛查下百度百科,它解釋還算不錯,你可以參考。

(1)個人認為非同步這種程式設計方式並不一定能提高執行效率(如果是單核來回切換指令流應該是有成本的),所以非同步的主要目的是為了提高響應性(或者說吞吐率)而不是效率(好多地方似乎把效率和吞吐率混為一談)是嗎?

完全正確,非同步是一定降低效率,但響應性提升使用者體驗,往往比效率重要,這是單使用者場景。如果是伺服器端,吞吐量是可以提高,卻也同時增加延遲,犧牲使用者體驗。為啥這樣決定?在單使用者場景,你的老闆經常是使用者,故你服務使用者;而在多使用者場景,你的老闆是資本家,故你服務資本家,犧牲使用者體驗。吞吐量提高,可以降低硬體成本,這是資本家想要的。

(2)個人認為非同步本質上都是並行的。比如在有DMA的裝置上非同步讀一個檔案,此時CPU去執行別的指令。那麼這個讀取過程可以認為是CPU和DMA並行工作(似乎兩個處理器並行才叫並行,一個處理器和其它硬體同時工作就不叫並行了)嗎?有透過併發實現的非同步嗎?

非同步本質上是併發,而非並行。非同步都是靠併發實現的,能並行更好,但不需要。為啥用兩個字表達一個意思呢?切入角度不同,非同步強調好處,併發關注解決非同步帶來的問題。好比權利與義務一體兩面,非同步強調權利,併發關注義務。

(3)回撥函式可以理解為是把依賴該非同步函式執行結果的後續程式碼做了一個封裝嗎?因為很難想象一個函式的執行結果不被後續的程式碼所依賴,所以一直很好奇非同步程式設計的適用場景是什麼,感覺大多數情況下程式碼都得一步一步地執行,前一步沒返回結果,後一步就不知道該怎麼辦。可是非同步程式設計居然允許一個函式還沒返回結果,後續程式碼就繼續執行,說明在這樣的程式中有一部分程式碼是不依賴該函式的返回結果的,而只將依賴的部分封裝成回撥函式傳給該函式,是這樣的嗎?

非同步通常處理 I/O 場景,即讀寫。讀當然需要回調,不然幹嘛讀?可寫就不必回撥啦。所以,有一半場景需要回調,另一半則不需要。

(4)是不是一般非同步函式都是用來作 I/O 事件處理的?程式的主邏輯應該都得按順序執行,只有事件處理的部分處理完就處理完了,不會有後續的程式碼依賴。比如同樣是讀寫一個檔案,如果這個程式就是為了處理這個檔案,那麼這個檔案只要還沒讀到記憶體中來,後續程式碼就絕對不能執行。但如果只是為了響應一個請求,那麼只需要把傳送response的程式碼封裝到回撥函式中。後續程式碼都與此事件無關。非同步程式設計還有哪些適用場景?

理論上,一切皆 I/O,包括跟人和其它機器互動也是 I/O。讀寫記憶體是 I/O,讀寫快取也算 I/O,啥非 I/O?非同步是用來解決速度差距的,譬如記憶體是硬碟的一百萬倍速度,沒有非同步,那每次讀寫都要等,豈不是慢死?等硬碟時,為啥不順道做其它運算?差距一百萬倍算小的,遠距溝通達萬億倍差距很正常的,非同步是程式設計師必備技能。

(5)個人認為非同步會發生資料短暫的不一致的情況。比如我在第x秒對知乎上的一個回答點了贊,然後另一個人在x+1秒也點開了這個回答。而因為如果點贊+1記錄的過程是非同步的,所以在x+1秒看到的既可能是之前的點贊數,也可能是+1後的點贊數?

這算併發問題。記住一點,好處都是非同步,問題(壞處)都是併發(跟病發同音),雖然兩字指同一件事,就像兩人結婚,成為一體,但女生永遠是對的,男生(跟難生同音)永遠是錯的。

(6)非同步是作業系統實現的,還是使用者空間就能實現的?非同步是為了防止阻塞而使得該程式被排程器直接掛起嗎?那同步非阻塞I/O和非同步又有什麼區別呢?如果在使用者態用協程實現非同步,可是如果一遇到阻塞的程式碼就被作業系統掛起,那還來不及切換協程就已經被掛起了。所以是不是允許使用者態先試探試探,遇到需要阻塞的程式碼時先讓OS別掛起,讓使用者程序先看看在眾多協程中還有沒有不需要阻塞的程式碼可以執行,儘量把時間片佔夠。那麼使用者程序是如何與OS相互配合實現非同步的?

非同步誰都可以實現,只不過作業系統實現效率高些,而硬體實現則效率更高。同步非阻塞 I/O?把那本書燒了,它不知道在說啥。都同步了,咋可能非阻塞,你執行緒自己沒被阻塞,算啥同步?這裡你描述混亂,不知說啥,但既然你提到時間片,我順道講講。非同步就是放棄自己的時間片,讓其它執行緒來用。當然,你如果有其它事能做,那就最好立馬去做,不必放棄時間片,只是絕大多數程式碼不會有其它事能做,故索性放棄當前時間片,算犧牲小我,完成大我的偉大舉動。這方法縱遠不及完美,然你對計算機理解不足,能應用非同步就好,別眼高手低。

(最後吐槽以下,感覺好多教程都是互相抄,為了非同步而非同步,沒說明白非同步的本質是什麼,有什麼優缺點,適用場景是什麼,不適合非同步的場景又是什麼)

的確,很多教程都胡說八道,燒了乾脆,譬如“同步非阻塞 I/O”是一關鍵字,看見立燒。不過也有另一可能,即教程太老,三五十年前寫的,指的是一種理想國狀態,目前尚無科技實現,新教程通常不提這個。拿起一本教程,第一件事就是檢查哪年出版,超過五年的教程基本可以淘汰,除非它一直不斷更新,且最近一次更新在五年內。計算機發展很快,超過三年的教程都算落伍了,給五年算很客氣了。

非同步的優缺點?再強調一次,非同步是女生,是絕對完美的,零缺點,記住這點就一生受用。非同步帶來的問題叫併發(病發),而高併發在履歷上好看,是因為如果你連這都能治,那肯定是牛醫生。倘若一定要說非同步有啥缺點,那就是慢熱,使用成本太高,達起碼數微秒,足以做好幾萬次整數加法,故如果 I/O 等待在幾十微秒內,非同步肯定不划算,太貴!