2012-02-27 19 views
9

會不會是一個很大的區別這兩scenarious:應用多線程與多實例 - 可以選擇哪一種?

  1. 一個實例創建100個線程來處理一些工作在同一應用程序的
  2. 10個實例創建10個線程每處理作業(總100)

兩種情況下的線程數都是相同的。這是一種表現還是對某種形式的改進?

實例 - 例如控制檯應用程序,所以在第二種情況下,它將012控制檯應用程序運行。每個應用程序都有自己的文件夾 。

+3

3.不要創建100個同時活動的線程,除非您在Cray上使用大量處理器。 – 2012-02-27 22:35:21

+0

你的流程需要溝通嗎? – Jimmy 2012-02-27 23:35:27

+0

對不正確的答案(已刪除)進行分析。我測試了上述場景,發現單進程多線程應用程序實際上比多進程應用程序更快。會試着自己理解原因。 – Jimmy 2012-02-28 01:21:30

回答

4

一個線程使用比一個進程更少的資源,所以理論上選項1會更好。然而,你可能不會注意到兩者之間有太大的區別,因爲100個獨立的線程處理所有同時運行,並爭取相同的操作系統資源幾乎保證讓你的系統停下來。

我會選擇選項3-一個包含相當小的線程池的進程。這樣,一些工作將同時執行,其他工作將排隊等待輪到他們。如果要運行大量的工作,這種方法也可以很好地擴展。

ThreadPool類,在其頂部上的許多較高級別的抽象或優選,一個(例如,task library,甚至普通老式asynchronous delegates)。

0

這樣一個奇怪的問題,很難找到實際的應用..但我會想象從性能的角度來看,選項1會更好。運行同一個應用程序的10個實例,看起來會有更多的工作要做。 (清理,註冊,控制檯打開等)

編輯* 因爲使用選項1,您可以排隊工作並讓線程處理負載。

2

選項2具有(至少)以下開銷:

  • 更多處理對象每個進程靜態存儲器
  • 更多
  • CLR和即時編譯代碼的多個實例
  • 上下文切換需要切換地址空間(非常昂貴)
  • 分享應用程序數據結構的機會較少
  • 您需要cr oss進程通信。簡單的方法調用成爲IPC操作
  • 爲臭蟲通過thread-無內置負載平衡你
  • 更多的機會(IPC通信,叉炸彈,...)
  • 更糟的可調試
  • 更多的工作池
  • 較難和更容易出錯的同步。減少內置的東西和慢

爲什麼你會選擇(2)如果你可以選擇(1)?有正當理由,但這些都是比較特殊的:

  • 您需要能夠容忍任意內存損壞。這是不正常的情況(根本不是!)
  • 你需要殺死線程的能力。對於單線程來說,這在CLR內部不能可靠地完成。但是你可以協同工作,無論如何這通常是更好的選擇
  • 你的線程需要在不同的用戶和其他用戶下運行。這幾乎不會發生。

一般來說,過程越少越好。

+0

我通過編輯添加了很多東西。 – usr 2012-02-27 22:39:07

1

是的,這將是一個很大的區別。每種方法都有優點和缺點:

  • 內存消耗。顯然,10個進程中的每一個都會要求創建自己的地址空間 等。雖然 溝通/同步線程相對容易(您可以使用關鍵部分,其中 是最有效的方法之一),但在 進程之間執行操作將更困難。在10個進程和10個線程的情況下,您必須執行兩種方法。
  • 崩潰。如果其中一個線程正在執行 錯誤,則整個過程都會死亡。

我個人更喜歡一個進程/許多線程。但是,這實際上取決於任務。

+0

OP是否說他的流程需要溝通? – Jimmy 2012-02-27 23:27:55

+0

我測試了實際場景,發現多個進程較慢。你是對的。我刪除了我的不正確答案。 – Jimmy 2012-02-28 01:16:26

2

這取決於你在做什麼,但在大多數情況下,選項1將具有最佳性能,並且將是最容易使用的。
爲了給你一個更完整的答案,我需要了解以下內容:

  • 是100個線程都執行相同的任務?
  • 100個線程是否訪問相同的數據?
  • 線程處理的任務是否會自然停機(等待另一個進程完成或資源可用)?
  • 線程處理的任務是否都嘗試訪問有限的資源(如硬盤或網卡)?
  • 您的計算機可以同時處理多少個併發線程(例如,具有超線程的4個核心處理器可以處理8個線程,沒有超線程的4個核心處理器可以處理4個線程)?
  • 如果線程出現問題會發生什麼情況?進程是否崩潰,線程是否重新啓動?

如果線程都執行相同的任務,讓他們一起將是最終用戶和開發人員後者更容易,因爲一切都在一個地方。

如果線程都訪問相同的數據,然後讓他們在同一個進程可以讓你線程之間共享數據,並降低內存足跡(修改數據時,雖然留意競爭條件)。您可能還可以組隊線程從相同的塊訪問數據,所以一切都可以在CPU上緩存,減少內存延遲的影響,雖然這不是我會建議嘗試。

由於許多答案都對如何實施項目提供諮詢,知道如果每個線程設計,充分利用CPU正在運行或在所有的時間,如果這些都是做的工作少量之前的後臺任務重新入睡將有助於我們針對您的情況提出正確的建議。

知道什麼是硬件的過程將運行在將幫助我們提供正確的建議您的具體情況。

如果一個線程失敗,會發生什麼?如果線程每天失敗一次,是否需要用戶進行干預,停止進程並重新啓動?如果是這樣,那麼在其他線程上完成的任何未保存的工作將會丟失。在這種情況下,讓每個線程都在自己的進程中運行,只會讓您失去失敗的進程。


Christian Hayter的選項3有意義,但並不總是與C#相關。
如果你看一下documentation,它指出:

了操作系統的ThreadId有一個託管線程沒有固定的關係,因爲非託管主機可以控制託管和非託管線程之間的關係。具體而言,複雜的主機可以使用CLR Hosting API根據相同的操作系統線程安排多個託管線程,或者在不同的操作系統線程之間移動託管線程。

基本上這意味着.net框架將集中你的線程,如果它感覺就像這將是一個不錯的主意。如果你的進程使用更多的線程,這很可能發生,而多線程進程之間的線程總數可能會保持非常相似。因此,我期望1進程,100線程解決方案使用更少的總線程,然後10個進程,每個10線程(大約10到40,但你必須檢查)。

這就是說,框架將被猜測,所以在某些情況下,線程池將是一個更好的選擇。請務必先閱讀documentation,因爲有些情況下不應使用線程池。有關泳池的快速教程可在MSDN上找到。還有一個討論何時使用線程池的thread


如果您提供更多信息,我會嘗試給出更準確的答案。否則選項1(可能選項3)在大多數情況下是更好的選擇。