2008-09-14 98 views
8

你如何使你的應用程序多線程? 你使用異步函數嗎? 或者你產生一個新的線程? 我認爲非同步功能已經產生線程,所以如果你的工作是做只是一些文件讀取,懶惰,只是在產卵一個線程你的工作也只是「浪費」 ressources ... 那麼,有沒有某種設計的時使用線程或異步函數?線程或異步?

回答

6

產卵線程只會浪費資源,如果你開始產卵,一兩個額外的線程是不會影響平臺proformance,事實上系統目前有超過70個線程對我來說,並且msn使用32 (我真的不知道一個信使如何使用這麼多的線程,當它最小化時並沒有真正做任何事情時,exspecialy ...)

用一個好時間來產生線程是什麼時候需要很長時間,但你需要繼續做其他事情。

例如說一個計算將需要30秒。最好的辦法是爲計算生成一個新線程,以便您可以繼續更新屏幕並處理任何用戶輸入,因爲如果您的應用程序凍結直到完成計算,用戶會討厭它。另一方面,創建線程幾乎可以立即完成某些事情幾乎是毫無意義的,因爲創建(或者甚至僅僅是將工作傳遞給使用線程池的現有線程)的開銷將高於只做首先是工作。

有時候,你可以把你的應用程序爲一對夫婦在其自己的線程中運行seprate部分。例如在遊戲中,更新/物理等可能是一個線程,而圖形是另一個線程,聲音/音樂是第三個,而網絡則是另一個。這裏的問題是你真的必須考慮這些部分如何相互作用,否則你可能會有更糟糕的表現,看似「隨機」發生的錯誤,甚至可能發生死鎖。

7

如果你正在談論的.Net,那麼不要忘記ThreadPool。線程池也是異步函數經常使用的。產生大量線程實際上會傷害你的表現。線程池被設計爲產生足夠的線程來以最快的速度完成工作。因此,請使用線程池來代替自己的線程,除非線程池不能滿足您的需求。

PS:而就在Parallel Extensions留意微軟

0

線程的使用讓你多想想你的應用程序需要線程,可以從長遠來看,更容易地改善/控制你的表現方式。
異步方法更快地使用,但他們有點神奇 - 很多事情發生,使他們有可能 - 所以這是可能的,在某些時候,你需要的東西,他們不能給你。然後,您可以嘗試並推出一些自定義線程代碼。
這一切都取決於你的需求。

2

我將第二Fire Lancer's答案 - 創建自己的線程是處理大任務或處理一個任務,否則將被「堵」,以同步的應用程序的其餘部分,你必須有一個極好的方法清楚地理解你必須以明確定義線程任務的方式解決和開發的問題,並限制它所做的工作範圍。

對於一個例子,我最近在工作 - 一個Java控制檯應用程序定期運行的基本屏幕抓取網址來捕獲數據,與DOM文檔的解析,提取數據,並將其存儲在數據庫中。

作爲一個單線程應用程序,它正如您所期望的那樣,佔用了一個年齡,平均每50kb頁面大約有1個url。不錯,但是當你擴大到需要批量處理數千個URL時,這是不好的。

分析應用程序顯示,大多數時候活動線程處於空閒狀態 - 它正在等待I/O操作 - 打開遠程URL的套接字,打開與數據庫的連接等。正是這種情況這可以通過多線程輕鬆改進。重寫是多線程的,只有5個線程而不是1個,即使在單個核心cpu上,也會增加超過20倍的吞吐量。

在這個例子中,每個「工作者」線程被明確限制爲它所做的 - 打開遠程的遠程URL,解析數據並將其存儲在數據庫中。所有的「高級」處理 - 生成URL解析列表,找出下一步處理錯誤,所有這些都保留在主線程的控制之下。

0

答案是「視情況而定」。

這取決於你想達到的目標。我會假設你的目標是獲得更多的表現。

最簡單的解決方案是找到另一種方法來提高你的表現。運行一個分析器。尋找熱點。減少不必要的IO。

下一個解決方案是將程序分解爲多個進程,每個進程都可以在自己的地址空間中運行。這是最簡單的,因爲沒有個別進程互相混淆的機會。

下一個解決方案是使用線程。在這一點上,你打開了一大堆蠕蟲,所以從小處着手,只是多線程化代碼的關鍵路徑。

下一個解決方案是使用異步IO。一般只建議人們編寫一些負載很重的服務器,即使如此,我寧願重新使用抽象出細節的現有框架之一,例如C++框架ICE或Java下的EJB服務器。

請注意,這些解決方案中的每一個都有多個子解決方案 - 有不同品種的線程和不同種類的異步IO,每個都有稍微不同的性能特徵,但通常最好讓框架爲您處理。