2009-11-17 31 views
4

我爲我的特定需求進行了優化的自定義ThreadPool。但是,當進程中有多個AppDomain時,CLR ThreadPool能夠在所有AppDomain中共享,並且我希望能夠重現此行爲。.Net如何創建跨進程的所有AppDomain共享的自定義ThreadPool?

這可以使用MarshalByRefObject和Remoting來完成,以創建一個分佈式的ThreadPool,但我擔心它會增加不需要的開銷,因爲自定義線程池的關鍵目標是性能。

另一個理論上的解決方案是使用非託管對象破解AppDomain內存邊界。如果我是正確的,AppDomain中的內存邊界僅適用於託管對象,所以每個AppDomain中都可能有一個託管包裝指向同一個非託管對象。

所以我的問題是:

  1. 有沒有一種方法,使利用遠程與 最小的開銷定製 線程池?
  2. 如果不是,是否可以在AppDomain之間共享一個非託管的 對象?
+0

是什麼促使編寫自定義線程池的決定? .NET線程池中缺少哪些功能? – Walter

+0

CLR ThreadPool無法優先排列隊列中的工作項。 CCR Dispatcher提供了一些很好的可能性,我認爲CCR Dispatcher和CLR ThreadPool之間的混合會很有趣。 –

回答

0

想到更多關於它的信息,嘗試重新實現一個進程範圍的ThreadPool可能是一個壞主意,CLR ThreadPool已經爲此進行了優化。

對於我而言,我希望更多的靈活性能夠排列到池中的工作項的優先級,這可以通過在現有的CLR ThreadPool之上構建的圖層來完成。

+0

這聽起來很實際。我想知道你如何做到這一點,同時避免上下文切換太多。我還需要一個跨應用程序域的線程池,但性能是關鍵。 – Wayne

+0

CLR ThreadPool已經是跨應用程序域。如果你想定製一個,我認爲「最簡單」的方法是在託管C++中完成。但是自從.NET 4以來,CLR ThreadPool已經得到了很好的優化,並且很難做得更好。我在CLR ThreadPool中看到的弱點是它沒有很好的隔離,任何一段代碼都會略微阻塞一個線程池的線程,這會影響到任何實時性能。如果我們可以創建一個CLR ThreadPool的獨立實例,那將是非常棒的。 –

+0

似乎在.Net 2.0 SDK中有一個Coop Fiber示例,它顯示瞭如何完全按照您的決定進行操作,它允許攔截所有對O/S和任何可能被阻止的同步對象的調用,因此您可以切換到不同的纖維。 – Wayne

2

在每個appdomain中創建一個新的線程池實例,但使用semaphore來控制在所有實例中運行的線程總數。這意味着您仍然可以獲得相同的總並行作業處理,但不要擔心編組。

MSDN文檔有一個示例。

+0

當每個cpu有一個線程時,線程池是最優的。使用您的解決方案,線程不會通過AppDomain共享。所以如果你有5個AppDomain排隊工作項目,並且只有4個cpu核心,那麼你需要5個線程來執行所有的工作項目,這不是最佳的。 –

+0

最適合什麼?如果你的線程可能是IO綁定的,那麼one-thread-per-cpu是非常不理想的。該框架的線程池原來最大爲25/cpu,現在爲250/cpu;從來沒有1/CPU。使用Threading.ThreadPool.GetMaxThreads()的信號量將模擬框架的當前操作。 隨着遠程處理,總是會有編組開銷,所以每個線程的啓動成本都會高於你可能想要的。至於共享一個非託管對象;聽起來像你給自己打開了一個痛苦和錯誤的世界。我不會這樣做。 –

+0

你說得對,我應該說cpu綁定處理的最佳選擇。但是,即使對於IO綁定處理,使用IO操作阻塞線程池線程也不是一個好主意,它應該使用IO完成端口。 –

相關問題