.NET 8 的 green thread 異步模型被擱置了

.NET 平臺上的green thread 異步模型實驗結果最近出來了,具體參見:https://github.com/dotnet/runtimelab/issues/2398 ,實驗結果總結一下就是在.NET和 ASP.NET Core中實現Green Thread是可行的。Green Thread 在.NET運行時環境中的基本成本和好處,以及與異步編程模型的交互和挑戰。如果引入了全新的異步編程模型,對於.NET開發人員來說,Green Thread 和現有異步模型async/await 之間的交互非常複雜。因此,決定暫停綠色線程試驗,繼續改進現有的async/await模型,以便在.NET中開發異步代碼。

文章對爲什麼要進行Green thread的實驗的總結一下就這麼幾點:

  1. .NET的異步編程模型簡化了應用程序的異步代碼編寫,對於增強I/O綁定方案的可伸縮性非常關鍵。
  2. I/O綁定代碼經常處於等待狀態,如等待網絡返回數據。異步代碼提高了可伸縮性,顯著降低了等待I/O的請求成本。
  3. 異步C#代碼的優勢是在等待I/O操作時的低成本,並且允許服務器並行處理大量請求。
  4. 但異步編碼也有挑戰,因爲開發者需要確定哪些方法應該異步化。全面異步化不現實,因爲異步方法有性能、類型限制,並且編程模型複雜。
  5. Green thread的目的是簡化編程模型,使得所有代碼可以以同步方式編寫,但仍保持可伸縮性和性能。
  6. Green thread在其他編程環境中已經被驗證爲有效,現在的考慮是它是否適用於C#,特別是考慮到存在的async/await模型。

文章裏也對擱置Green thread的結論總結幾點:

  1. Green thread爲.NET開發人員提供了一個全新的異步編程模型。 asp. net core benchmark 顯示 green thread 性能不如現有的 async/await,async/await 達到 178,620 rps 的同時 green thread 只達到了 162,019 rps, .NET 平臺是目前爲止唯一一個同時實現了Green Thread 和async/await 異步模型的平臺,這就讓我們有了一個橫向比較兩種編程模型的平臺,這也就破案了在社區中 異步編程模型哪個更快的爭論,這裏有個非常好的面試題就說 golang,nodejs,java等等他們實現的異步編程模型分別是哪一種,他們有什麼優缺點等。
  2. Green thread與現有的異步模型之間的交互是複雜的。特別是從Green thread代碼調用異步方法需要轉換到異步代碼的同步模式,這在常規線程上不是一個好的選擇。 micro benchmark 顯示深 green thread 調用棧的性能遠不如深 async/await 調用鏈。
  3. 在Green thread模型中,與本機代碼的互操作性是複雜和相對較慢的。基於P/Invoke的基準測試顯示,Green thread上的操作成本明顯增加。 100,000,000 次 P/Invoke 從原來的 300ms 變成需要 1800ms。
  4. Green thread在與某些特定特性如線程局部靜態變量和本機線程狀態交互時存在功能上的問題。 thread local 變量的支持以及暴露 native thread 狀態變得非常難以實現。
  5. Green thread與某些安全緩解措施,如防止面向返回的編程的影子堆棧( shadow stacks),的交互是具有挑戰性的。
  6. 在某些關鍵場景中,Green thread模型的速度有可能超過異步,但這種性能提升的代價是其他場景下的性能下降,以及需要放棄一些兼容性和特性。
  7. 一個未解之謎是,通過優化異步,是否可以讓Green thread在性能上超過異步。
  8. 開發團隊發現以上問題在其它使用 green thread 的語言中同樣存在。

文章後面的討論值得看一看,其中rcollette 的觀點特別有意思:https://github.com/dotnet/runtimelab/issues/2398#issuecomment-1713003525 

這篇關於loom/Java 21的演講對於那些希望深入瞭解綠色線程的人來說非常不錯。 https://blog.jetbrains.com/idea/2023/05/new-livestream-virtual-threads-and-structured-concurrency-in-java-2021-with-loom/

我預計在現實世界中,它們(對現有代碼)有益的情境會非常有限。你需要大量的阻塞IO,對嗎?到線程池飢餓成爲一個問題的程度。

在Java世界中,這很快就會發生,原因有以下幾點:

  1. Java沒有標準的非阻塞數據庫驅動規範。Java在開始研究綠色線程之前應該先解決這個問題。容易說“你的操作持續時間太長”,但有些事務本質上運行時間很長,並且有時候你無法控制。這是主要的問題。
  2. 對於一些開發人員來說,反應式異步模式/API是一個心智跳躍,他們只是試圖避免它(並不是說這是對的,但這種情況經常發生)。這比JS中的Promise嵌套還要糟糕。對於你使用的每一個方法,你都必須考慮我是否返回相同的類型,我是否返回另一個promise(Future),我是處理一個集合還是單個值,都需要不同的方法調用,等等。你還會遇到線程上下文的情況,比如事務,日誌MDC等,在反應式模型中似乎毫無理由地失敗,這再次讓開發人員失去信心。說“他們是開發人員,他們應該做得對或離開這個行業”都把責任推到了平臺開發者身上來提供優雅的解決方案。這是Java存在的一個問題,並且坦白說,我不希望這種情況在.NET中發生,因爲Java中這種不夠優雅的原因正是我更喜歡.NET的原因。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章