999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

線程池設計與動態優化

2008-12-31 00:00:00趙衛東王志成韓下林
電腦知識與技術 2008年36期

摘要: 線程池是提高服務器程序性能的一種很好技術,已經在服務器端應用程序得到了廣泛應用,比如Web服務器、數據庫服務器、代理服務器和網絡游戲服務器等。尤其面對海量并發連接時,線程池對能顯著提高系統整體性能。該文提出了一種輕量級的、高效的線程池設計方案,在實際的網絡服務器應用應用取得了非常好的效果。

關鍵詞:線程池;多線程;任務隊列;性能;動態優化

中圖分類號:TP316文獻標識碼:A文章編號:1009-3044(2008)36-2753-03

Design and Dinamic Optimization of Thread Pool

HU Meng1,2, ZHAO Wei-dong1,2, WANG Zhi-cheng1,2, HAN Xia-lin1,2

(1.State Education Commission Engineering Center for Enterprise Digital Technology, Shanghai 200092, China;2.Research Center of CAD, Tongji University, Shanghai 201804, China)

Abstract: Thread pool is a excellent technology to improve the performance of the server, it has been widely applied in the server applications, such as Web servers, database servers, proxy servers and network game servers. In particular, faced with a deluge of concurrent connection, the thread pool can significantly improve overall system performance. This paper come up with a lightweight, efficient design of the thread pool, it achieved a very good result in the actual application of network server applications.

Key words: thread Pool; multi-threading; task queue; performance; dinamic optimization

1 引言

諸如 Web服務器、數據庫服務器、文件服務器或郵件服務器之類的許多服務器應用程序都需要處理來自遠程的大量小任務[1]。請求以某種方式到達服務器,這種方式可能是通過網絡協議(例如 HTTP、FTP 或 POP)、通過 JMS 隊列或者可能通過輪詢數據庫。不管請求如何到達,服務器應用程序中經常出現的情況是:單個任務處理的時間很短而請求的數目卻是巨大的。

構建服務器應用程序的一個過于簡單的模型應該是:每當一個請求到達就創建一個新線程,然后在新線程中為請求服務。實際上,對于原型開發這種方法工作得很好,但如果試圖部署以這種方式運行的服務器應用程序,那么這種方法的嚴重不足就很明顯。每個請求對應一個線程(thread-per-request)方法的不足之一是:為每個請求創建一個新線程的開銷很大;為每個請求創建新線程的服務器在創建和銷毀線程上花費的時間和消除了創建和銷毀線程的開銷之外,活動的線程也消耗系統資源。在一個 JVM 里創建太多的線程可能會導致系統由于過度消耗內存而用完內存或“切換過度”。為了防止資源不足,服務器應用程序需要一些辦法來限制任何給定時刻處理的請求數目。

線程池[2]為線程生命周期開銷問題和資源不足問題提供了解決方案。通過對多個任務重用線程,線程創建的開銷被分攤到了多個任務上[1]。其好處是,因為在請求到達時線程已經存在,所以線程創建所帶來的延遲被消除。這樣,請求能被立即處理,使得應用程序響應更快。為了獲得最佳的系統性能,線程池的大小應該是個可以動態調整的參數。比如,當某時刻頁面請求量很大時,Web服務器可以增加工作線程的數量;請求數量減少時,可以銷毀一定數量線程,以便節省系統資源。線程池的大小不能超過一個閾值[3],不然系統整體性能會下降。

2 線程池的實現

2.1 線程池的架構

盡管目前已經存在一些非常優秀的線程池實現,比如著名的C++庫集合Boost和網絡通信庫ACE中線程池實現。但這些都是非常重量級的實現,鑒于此,筆者用標準C++和Windows 線程API實現了一個非常輕量級、靈活的線程池,實驗結果表明該線程池能顯著改善服務器應用程序性能。

線程池主要分成三個部分,即線程池、任務隊列、性能檢測和調優模塊。如圖1所示。

2.2 線程池與工作隊列的設計

線程池中包含是一定數量可以復用的工作線程,線程池也是一種對象池,和其他的對象池(如連接池)有相同的地方,目的是在使用相關的對象時能夠避免創建和銷毀對象帶來的資源消耗,使得程序響應更快。但線程和其他普通的對象也有不同,線程包含一個指令指針,還包括其他資源,如運行時的函數激活記錄的堆棧、一組寄存器和線程特有的數據。所以線程池的管理和其他對象池的管理就有很多的不同。

在開始設計線程池的時候,首先可以先考慮一下連接池的使用場景。一般是由主線程主動地從池里面獲取一個連接,主線程用完再把連接返回給池。主線程對連接對象的使用,就是調用連接對象的方法(按面向對象的說法,就是給對象發送消息)。

按連接池的使用場景,要實現線程池,首先要有一個線程對象。當主線程從池里面獲得一個線程之后,主線程要能夠向這個線程發送消息,以達到主線程使用線程的目的。那么這個線程對象需要能夠支持主線程向線程池的線程發送消息。通過閱讀pthread的規范,可以了解到pthread_cond_wait是POSIX 線程信號發送系統的核心。主線程要發送給線程池線程的信息還包括這次任務的參數:一個函數指針和提供給這個函數的參數。

在上面的第二點中,只考慮了如何從線程池獲得線程,并使用線程,而沒有考慮如何在使用完線程之后如何把線程歸還給池。連接池的使用場景中,通常是有主線程來完成這個操作。但是在線程池的使用場景中,主線程在發送消息之后,通常就不再等待這個線程完成任務。即主線程通常只負責取,但不負責還。考慮到這一點,就需要在每個線程對象中記錄自己所屬的池,當完成任務之后,線程主動把自己歸還到池里面。

此我們可以設計出線程對象的數據結構:

typedef struct _thread_st {

pthread_t id; //線程ID

pthread_mutex_t mutex; //互斥對象

pthread_cond_t cond; // 條件變量

dispatch_fn fn; //函數指針

void *arg; // 函數的參數

threadpool parent; // 線程池

};

線程池對象的數據結構是

tpedef struct _threadpool_st {

sp_thread_mutex_t tp_mutex;

sp_thread_cond_t tp_idle;

sp_thread_cond_t tp_full;

sp_thread_cond_t tp_empty;

_thread ** tp_list;

int tp_index;

int tp_max_index;

int tp_stop;

int tp_total;

} threadpool_st;

任務隊列的設計非常簡單,提供一種緩存機制,用于存放將從網絡層接收的數據包。

2.3 性能檢測與調整

性能檢測與優化模塊動態地檢測系統的性能,如果性能由于用戶載荷改變導致性能下降,該模塊動態調整系統的參數,達到優化的效果。線程池在很多應用中可以高效提供服務,線程池中并行線程的多少決定了線程池的效率。線程池越大,并行處理用戶請求的能力越大。然而,當線程池大到一定時候,系統為了維護線程所花的代價高于因為線程池所帶來的好處,系統的性能將降低。本文主要研究根據線程池中某些可以得到的某些系統特征數據來動態改變線程池的大小。該模塊的功能主要有兩個:檢測系統某些選定的特定數據,然后根據所得數據評估系統的性能狀態;如果系統性能下降,根據數據來增大或減小線程池的大小,從而達到提高線程池性能的目的。

圖1 線程池系統架構

3 線程池性能測試

3.1 測試環境配置

本實驗測試環境是:CPU:AMD Turion 64 內存:1024MB,網絡:100MB局域網 操作系統:Windows XP Professional SP2。

3.2 測試結果

本文選擇系統吞吐量做為線程池性能測試標準,吞吐量被簡單定義為單位時間系統處理的任務數量,系統中定義的NUM_LOOPS用于模擬任務執行的時間,NUM_LOOPS值越大說明服務器系統需要的計算時間越長,以下是為了實驗設計的測試數據:

1) threads in pool = 1 and NUM_LOOPS=1, 100, 1000, 10000, 100000, 500000

2) threads in pool = 2 and NUM_LOOPS=1, 100, 1000, 10000, 100000, 500000

3) threads in pool = 4 and NUM_LOOPS=1, 100, 1000, 10000, 100000, 500000

4) threads in pool = 8 and NUM_LOOPS=1, 100, 1000, 10000, 100000, 500000

5) threads in pool = 16 and NUM_LOOPS=1, 100, 1000, 10000, 100000, 500000

6) threads in pool = 32 and NUM_LOOPS=1, 100, 1000, 10000, 100000, 500000

測試結果如圖2所示。

實驗結果表明使用線程池對系統性能提高是顯著的,隨著線程池尺寸的增加,系統性能會逐步提高,并達到一個穩定的值。

3.3 線程池的注意事項[1]

雖然線程池是構建多線程應用程序的強大機制,但使用它并不是沒有風險的。在使用線程池時需注意線程池大小與性能的關系,注意并發風險、死鎖、資源不足和線程泄漏等問題。

1) 線程池大小。多線程應用并非線程越多越好,需要根據系統運行的軟硬件環境以及應用本身的特點決定線程池的大小。一般來說,如果代碼結構合理的話,線程數目與CPU數量相適合即可。如果線程運行時可能出現阻塞現象,可相應增加池的大小;如有必要可采用自適應算法來動態調整線程池的大小,以提高CPU的有效利用率和系統的整體性能。

2) 并發錯誤。多線程應用要特別注意并發錯誤,要從邏輯上保證程序的正確性,注意避免死鎖現象的發生。

3) 線程泄漏。這是線程池應用中一個嚴重的問題,當任務執行完畢而線程沒能返回池中就會發生線程泄漏現象。在Java中發生線程泄漏的一種常見情況是沒能捕獲Runtime Exception或Error對象。在上述示例代碼中,對Runtime Exception異常的捕獲便是為了防止線程泄漏而采取的必要措施。

4) 為不同的線程模式進行設計。在Java中線程模式有兩種:協作式線程模式和搶占式線程模式。具體采用何種線程模式由Java虛擬機的實現來決定。兩種模式在線程切換調度有所區別,需要根據不同的線程模式以及應用的特點作出相應的調整

4 線程池動態優化

簡單線程池存在一些問題,比如如果有大量的客戶要求服務器為其服務,但由于線程池的工作線程是有限的,服務器只能為部分客戶服務,其它客戶提交的任務,只能在任務隊列中等待處理。一些系統設計人員可能會不滿這種狀況,因為他們對服務器程序的響應時間要求比較嚴格,所以在系統設計時可能會懷疑線程池技術的可行性,但是線程池有相應的解決方案。動態優化[3,4]線程池尺寸是高

級線程池要解決的一個問題。主要有下列解決方案。

方案一:動態增加工作線程

在一些高級線程池中一般提供一個可以動態改變的工作線程數目的功能,以適應突發性的請求。一旦請求變少了將逐步減少線程池中工作線程的數目。當然線程增加可以采用一種超前方式,即批量增加一批工作線程,而不是來一個請求才建立創建一個線程。批量創建是更加有效的方式。該方案還有應該限制線程池中工作線程數目的上限和下限。否則這種靈活的方式也就變成一種錯誤的方式或者災難,因為頻繁的創建線程或者短時間內產生大量的線程將會背離使用線程池原始初衷—減少創建線程的次數。

方案二:優化工作線程數目

如果不想在線程池應用復雜的策略來保證工作線程數滿足應用的要求,你就要根據統計學的原理來統計客戶的請求數目,比如高峰時段平均一秒鐘內有多少任務要求處理,并根據系統的承受能力及客戶的忍受能力來平衡估計一個合理的線程池尺寸。線程池的尺寸確實很難確定,所以有時干脆用經驗值。

方案三:一個服務器提供多個線程池

在一些復雜的系統結構會采用這個方案。這樣可以根據不同任務或者任務優先級來采用不同線程池處理。

這三種方案各有優缺點。在不同應用中可能采用不同的方案或者干脆組合這三種方案來解決實際問題。

圖2 使用線程池的系統測試結果

5 結束語

本文提出了一種輕量級的、靈活的線程池設計方案,實驗結果表明線程池技術對于服務器程序的性能改善是顯著的。線程池技術在服務器領域有著廣泛的應用前景,在筆者開發的服務器應用程序中是經常用到的一項技術,一般也是高性能服務器程序比較核心的功能模塊。

參考文獻:

[1] Java theory and practice: Thread pools and work queues[EB\\OL].http://www.ibm.com/developerworks/library/j-jtp0730.html.

[2] Wikipedia,Thread Pool Pattern[EB\\OL].http://en.wikipedia.org/wiki/Thread_pool.

[3] Xu D P, Bode B. Performance Study and Dynamic Optimization Design for Thread Pool Systems[DB/OL][2004-12-01].http://www.scl.ameslab.gov/Publications/Brett/CCCTFinal-color.pdf.

[4] Ling Y B,Mullen T,Lin X L.Analysis of Optimal Thread Pool size[J].ACM Sl GOPS Operating System Review,2000,34(2):42-55.

[5] 王華,馬亮,顧明.線程池技術研究與應用[J].計算機應用研究,2005,22(11):141-142.

主站蜘蛛池模板: 特级精品毛片免费观看| 亚洲福利视频网址| 伊人欧美在线| 中文字幕亚洲综久久2021| 欧美精品不卡| 五月六月伊人狠狠丁香网| 青草精品视频| 国产精品中文免费福利| 99re在线免费视频| 视频在线观看一区二区| 色天天综合| 国产精品福利在线观看无码卡| 婷婷色中文| 99re这里只有国产中文精品国产精品| 二级特黄绝大片免费视频大片 | 国语少妇高潮| 成人字幕网视频在线观看| 日本午夜在线视频| 久久亚洲国产最新网站| 国产成人8x视频一区二区| 伊人色在线视频| 天堂av高清一区二区三区| 国产女人综合久久精品视| a级毛片免费网站| 婷婷午夜影院| 男人天堂伊人网| 亚洲乱码在线视频| 九九九久久国产精品| 亚洲色图在线观看| 免费欧美一级| 国产人在线成免费视频| 99精品国产高清一区二区| 亚洲av无码人妻| 久久国语对白| 精品国产欧美精品v| 国产麻豆另类AV| 亚洲天堂视频在线免费观看| 伊人久综合| 国产视频资源在线观看| 最新国产午夜精品视频成人| 亚洲成AV人手机在线观看网站| 亚洲IV视频免费在线光看| 女人毛片a级大学毛片免费| 亚洲欧美日韩天堂| 一区二区三区在线不卡免费 | 91精品国产情侣高潮露脸| 99国产在线视频| 五月婷婷精品| 国产成人精品高清不卡在线| 国产男人的天堂| 亚洲中文无码av永久伊人| 熟妇丰满人妻| 久久美女精品国产精品亚洲| 伊大人香蕉久久网欧美| 91麻豆精品国产高清在线| 欧美午夜视频在线| 中国美女**毛片录像在线| а∨天堂一区中文字幕| 亚洲性色永久网址| 国产精品手机在线观看你懂的| 精品亚洲麻豆1区2区3区| 99久久国产精品无码| 热久久综合这里只有精品电影| 美女无遮挡拍拍拍免费视频| 毛片一级在线| 日本午夜影院| 极品国产在线| 免费AV在线播放观看18禁强制 | 伊人成人在线| 日本午夜精品一本在线观看| 精品福利视频网| 亚洲精品第一页不卡| 亚洲日本中文字幕天堂网| 在线观看视频99| 2022国产无码在线| 一本大道视频精品人妻| 国产精品网址你懂的| 国产成人喷潮在线观看| 永久毛片在线播| 香蕉伊思人视频| 美女视频黄又黄又免费高清| 午夜无码一区二区三区在线app|