簡體   English   中英

要創建多少個線程?

[英]How many threads to create?

我現在正在學習如何編寫多線程程序,並且我對一個程序有幾個最佳線程有一個假設性的問題。

讓我描述兩種情況。

第一種情況是,我有一個容易使用多線程的程序,但是每個線程都將做很多工作(每個線程的執行時間約為幾秒鍾)。

第二種情況是,我有一個程序也很容易成為多線程,但是每個線程的執行時間非常短,大​​約為毫秒。

在這兩種情況中的任何一種情況下,對程序進行多線程處理的最有效方法是什么? 是創建系統內存允許的線程數量,還是在創建新線程之前等待線程完成,這樣我一次最多只能運行4個工作線程。

一方面,許多線程在內核之間切換線程時可能會產生開銷問題(據我所知,它並不是那么嚴重的開銷)。 另一方面,如果我限制正在運行的線程數,那意味着我將運行額外的檢查條件,並鎖定和解鎖計數器變量以跟蹤正在運行的線程數,並在舊線程完成時創建新線程。

我可以看到,如果有許多小線程,最好在可能的情況下盡可能多地使我的系統過載,因為在線程完成運行之前不會有太多的線程切換。 這將節省我不斷跟蹤線程數量的開銷。

另外,如果只有幾個大線程(幾個,我的意思是幾百個左右),那么跟蹤線程是有意義的,這樣我們就可以將線程保持在最佳數量,這樣就可以有很多線程切換(因為開銷會更大,因為我們可能會在單個線程完成之前進行多次切換)。

那么這些假設對每種情況都是正確的,還是有一種通用的做事方法在所有情況下都是正確的?

注意:這是假設一個多核心系統(現在,讓我們忽略超線程),而忽略與多線程相關的任何典型問題(假設所有線程都有私有寫位置,並且只能從公共線程讀取,鎖定和解鎖只會發生在增加或減少活動線程數的計數器時)。

謝謝,

-法肯

方案1:創建n個線程,其中“ n”是CPU內核數

方案2:相同,但是不要像在.NET Parallel Framework中那樣始終使用基於工作項/線程池的方法來始終創建和殺死線程。

編輯 :這是一篇很好的文章,涵蓋了#2- http://msdn.microsoft.com/zh-cn/magazine/cc163340.aspx ; 讓PFx找出要運行的線程數,您只需描述任務之間的關系即可。

通常的方法是使線程數可配置,並在幾種配置之間分析應用程序性能。

還要注意,在許多情況下,這不是與許多線程或上下文切換相關的開銷,而是由於同步訪問共享資源而導致的瓶頸,從而導致多線程應用程序效率低下。 即使您認為您的代碼是防死鎖的,如果有大量的IO正在進行,糟糕的同步實現也可能有效地扼殺並行化本來可以為您帶來的任何好處。

這不是一個可以一成不變的答案的問題,盡管有幾點要點:

由於線程壽命很短,也許您應該考慮使用池來管理它們? 您可以創建一個具有多個線程的池,該線程適合於主機系統和任務配置文件(例如,每個內核都一個),然后將其工作以某種隊列的形式進行。 通過這樣做,您消除了啟動新線程,為每個任務分配一個堆棧等的開銷。

至於池中適當的線程數,這取決於您正在運行的任務的類型。 如果它們是受CPU約束的任務,那么每個CPU一個線程是一個合適的選擇:避免在不需要時進行上下文切換。 另一方面,如果它們是與IO綁定的任務,例如執行套接字通信的線程,那么您可能希望將這個數字加倍,以便在等待IO輸入時更好地利用處理器。

總之,對於這種東西,沒有一種千篇一律的方法。 像往常一樣,剖析您的代碼,以找出效率低下的地方,並根據結果進行調整。

假設您的意思是Windows程序,即使它是C ++而不是dot-Net程序,它也將使您在開始之前瀏覽一下Joe Duffy的“ Windows並行編程”。 他非常擅長使用Windows提供的線程池例程,這很有說服力,因為它們已經在內部調整了處理器配置,從而減輕了負擔。
如果您無論如何繼續努力,那么本書中所討論的陷阱無疑將使您免於陷入標准陷阱。

我將從一個足夠好的數字開始,然后收集統計信息以找出正確的線程數來運行以達到良好的性能。

線程並不便宜。 我知道使用它們的兩個基本原因:

  1. 為了使多個硬件並行工作,無論它們是CPU內核,磁盤頭,某種其他類型的機器,還是世界另一端的服務器。

  2. 讓多個人並行工作,例如擁有自己會話的用戶。 此處的優勢不是速度,而是編碼每個用戶的交互序列的簡便性。

或兩者兼而有之,就像您需要處理一個線程,而對用戶進行響應一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM