async-await:協作排程 vs 搶佔排程
執行緒是為了並行化計算密集型任務。然而,如今,許多應用程式都是 I/O(輸入/輸出)密集型應用程式。
這樣,執行緒就有兩個重大問題:
- 他們使用大量(與其他解決方案相比)記憶體
- 啟動和上下文切換的成本可以在大量(數萬個)執行緒執行時感受到。
在實踐中,這意味著通過使用執行緒,我們的應用程式將花費大量時間等待網路請求完成並使用比必要更多的資源。
從程式設計師的角度來看,async/await提供了與執行緒相同的東西:併發性、更好的硬體利用率、更高的速度,但對於 I/O 繫結的工作負載具有顯著更好的效能和更低的資源使用率。
什麼是I/O 繫結工作負載?這些任務大部分時間都在等待網路或磁碟操作完成,而不是受到處理器計算能力的限制。
執行緒是很久以前設計的,當時大多數計算都不是網路(Web)相關的東西,因此不適合太多併發 I/O 任務。
正如我們從 Jim Blandy 所做的這些測量中看到的那樣,使用非同步的上下文切換比使用 Linux 執行緒快大約 30%,並且使用的記憶體減少了大約 20 倍。
在程式語言世界中,處理 I/O 任務的方式主要有兩種:搶佔式排程和協作式排程。
搶先排程
搶佔式排程是指任務的排程不受開發人員控制,完全由執行時管理。無論程式設計師是啟動同步任務還是非同步任務,程式碼都沒有區別。
例如,Go程式設計依靠的是搶佔式排程。
它的優點是更容易學習:對於開發者來說,同步和非同步程式碼之間沒有區別。另外,它幾乎不可能被濫用:執行時負責處理一切。
下面是一個在Go中進行HTTP請求的例子:
resp, err := http.Get("http://kerkour.com") |
僅僅通過看這個片段,我們無法判斷http.Get是I/O密集型還是計算密集型。
其缺點是。
- 速度,受限於執行時Runtime的聰明程度。
- 難以除錯bug。如果執行時有bug,可能極難發現,因為執行時被開發者當成了黑暗魔法。
合作排程
另一方面,在合作式排程下,開發者負責告訴執行時Runtime一個任務何時要花一些時間來等待I/O。
也就是要等待?是的,你明白了。這正是 await 關鍵字的目的。
這是給執行時(和編譯器)的指示,任務將花費一些時間來等待操作完成,因此計算資源可以在此期間用於其他任務。
它的優點是速度極快。基本上,開發者和執行時一起工作,和諧相處,以最大限度地利用處置時的計算能力。
合作排程的主要缺點是它更容易被濫用:如果一個等待被遺忘(幸運的是,Rust編譯器會發出警告),或者事件迴圈被阻塞超過幾微秒,就會對系統的效能產生災難性的影響。
其推論是,一個async 程式應該極其小心地處理計算密集型操作。
下面是一個用Rust進行HTTP請求的例子。
let res = reqwest::get("https://www.rust-lang.org").await?; |
.await 關鍵字告訴我們,reqwest::get 函式預計需要一些時間來完成。
相關文章
- linux搶佔式排程Linux
- Go 的搶佔式排程Go
- Go1.12將支援搶佔式goroutine排程Go
- Flink排程之排程器、排程策略、排程模式模式
- Go runtime 排程器精講(十):非同步搶佔Go非同步
- kube-scheduler原始碼分析(3)-搶佔排程分析原始碼
- swoole 協程原始碼解讀 (協程的排程)原始碼
- 非可搶佔式和搶佔式程式排程的區別是什麼?
- 多機器人協作排程問題機器人
- 圖解協程排程模型-GMP模型圖解模型
- Go runtime 排程器精講(九):系統呼叫引起的搶佔Go
- go1.14 基於訊號的搶佔式排程實現原理Go
- kubernetes 排程
- 解決方案| 快對講排程系統:高效協作
- Go runtime 排程器精講(五):排程策略Go
- Spark中資源排程和任務排程Spark
- 排程器簡介,以及Linux的排程策略Linux
- Go語言排程器之主動排程(20)Go
- Go排程器系列(3)圖解排程原理Go圖解
- Go 併發程式設計 - runtime 協程排程(三)Go程式設計
- Go runtime 排程器精講(八):執行時間過長的搶佔Go
- Pod的排程是由排程器(kube-scheduler)
- Go語言排程器之排程main goroutine(14)GoAI
- Go排程器系列(2)巨集觀看排程器Go
- 【深入理解Go】協程設計與排程原理(下)Go
- 【深入理解Go】協程設計與排程原理(上)Go
- Golang 的 協程排程機制 與 GOMAXPROCS 效能調優Golang
- oracle排程程式作業dbms_schedulerOracle
- oracle使用DBMS_SCHEDULER排程作業Oracle
- 資料排程
- Laravel Scheme排程LaravelScheme
- 雲排程概述
- Kubernetes 排程器
- 任務排程
- linux程式排程Linux
- k8s排程器介紹(排程框架版本)K8S框架
- libgo原始碼分析之多執行緒協程管理和排程Go原始碼執行緒
- 2.2.5排程演算法:時間片輪轉、優先順序排程、多級反饋排程演算法