Skip to Content

WWW 0x09: 到底要不要擔心 blocking

A programmer had a problem. He thought to himself, “I know, I'll solve it with threads!". has Now problems. two he

— Davidlohr Bueso

這裡是 WWW 第玖期,Wow Weihang Weekly 是一個毫無章法的個人週刊,出刊週期極不固定,從一週到五年都有可能。初期內容以軟體工程為主,等財富自由後會有更多雜食篇章。

Stop worrying about blocking: the new async-std runtime, inspired by Go

async-std 是 Rust 非同步生態中兩雄之一,欲與 tokio 爭天下。這次的實驗性更新受到 Go 語言啟發,實作了新的 scheduler,主要特點有:

  • 更快更好更自適應
  • 自動偵測 blocking task 並將其卸載到其他執行緒,避免阻塞
  • 使用者可在 async context 內呼叫 blocking task 而不阻塞

要點重申:你不需函式是 blocking 還是 non-blockging,全丟到 async 裡面呼叫吧!async-std 的 runtime 會偵測,然後幫你解決一切。

但事情往往沒這麼單純 😈

Do NOT stop worrying about blocking in async functions!

async-std 新的 scheduler 在處理 nested Future 或是使用其他非 async-std 的 select! 等 macro 時,blocking call 仍然會 block。這個 Reddit 討論串認為 async-std 不應該讓大家對 blocking function 降低警覺,否則一個 async library 就沒辦法替換其他沒有提供「自動偵測 blocking」的 runtime,會造成社群更加分裂。

其中也提到了 withoutboats 在 Interal forum 提及的 #[might_block] attribute,這是一個非常有趣的標記,類似 #[must_use] 告知 compiler 這個 function 會 block。不過另一方面,也有人提出 blocking/non-blocking 其實並非一邊一國:取得 array slice 中的元素是 non-blocking,但如果 array 實際上是 mmap 映射出來的檔案,取得元素就會有 page fault 然後就真的需要「讀檔」。

有人在 PR 提問,如果 async-std 新的 scheduler 賣點是可在 async block 使用 blocking function,是否產生一堆執行緒,造成 C10k 問題?async-std 團隊正式回應是,其實只會產生一個執行緒,和 10000 個 socket,當然,整個討論串仍持續進行,非常值得一讀。

有人提到 C10k 其實應該用 semaphore 解決,這的確是比較正確直觀的作法,畢竟,你知道你的函式是什麼顏色嗎

如果这篇文章说不清epoll的本质,那就过来掐死我吧!

這是在知乎專欄上的三篇文章,從硬體,歷史沿革,到實際程式碼來說明 epoll(7) 到底為什麼如此高效。

如果你之前就理解 epoll,看看是否可以回答下列問題,若覺得不是很透澈,再讀一遍吧!

  • 知道 Unix/Linux 上的 file descriptor 是什麼
  • 知道 epoll 透過 CPU 中斷來接收網卡數據的流程
  • 知道 kernel 和 socket 如何處理 buffer 來喚醒 process
  • 知道 select(2) 的實作原理
  • 知道 select 什麼情境可能會比 epoll 更有效率