由于伺服器的硬體資源“充裕”,那麼提高伺服器性能的一個很直接的方法就是以空間換時間,即“浪費”伺服器的硬體資源,以換取其運作效率。這就是池的概念。池是一組資源的集合,這組資源在伺服器啟動之初就完全被建立并初始化,這稱為靜态資源配置設定。當伺服器進入正式運作階段,即開始處理客戶請求的時候,如果它需要相關的資源,就可以直接從池中擷取,無需動态配置設定。很顯然,直接從池中取得所需資源比動态配置設定資源的速度要快得多,因為配置設定系統資源的系統調用都是很耗時的。當伺服器處理完一個客戶連接配接後,可以把相關的資源放回池中,無需執行系統調用來釋放資源。從最終效果來看,池相當于伺服器管理系統資源的應用設施,它避免了伺服器對核心的頻繁通路。
池可以分為多種,常見的有記憶體池、程序池、線程池和連接配接池。
記憶體池是一種記憶體配置設定方式。通常我們習慣直接使用new、malloc等系統調用申請配置設定記憶體,這樣做的缺點在于:由于所申請記憶體塊的大小不定,當頻繁使用時會造成大量的記憶體碎片并進而降低性能。
記憶體池則是在真正使用記憶體之前,先申請配置設定一定數量的、大小相等(一般情況下)的記憶體塊留作備用。當有新的記憶體需求時,就從記憶體池中分出一部分記憶體塊,若記憶體塊不夠再繼續申請新的記憶體。這樣做的一個顯著優點是,使得記憶體配置設定效率得到提升。
程序池和線程池相似,是以這裡我們以程序池為例進行介紹。如沒有特殊聲明,下面對程序池的描述也适用于線程池。
程序池是由伺服器預先建立的一組子程序,這些子程序的數目在 3~10 個之間(當然這隻是典型情況)。線程池中的線程數量應該和 CPU 數量差不多。
程序池中的所有子程序都運作着相同的代碼,并具有相同的屬性,比如優先級、 PGID 等。
當有新的任務來到時,主程序将通過某種方式選擇程序池中的某一個子程序來為之服務。相比于動态建立子程序,選擇一個已經存在的子程序的代價顯得小得多。至于主程序選擇哪個子程序來為新任務服務,則有兩種方法:
1)主程序使用某種算法來主動選擇子程序。最簡單、最常用的算法是随機算法和 Round Robin (輪流算法)。
2)主程序和所有子程序通過一個共享的工作隊列來同步,子程序都睡眠在該工作隊列上。當有新的任務到來時,主程序将任務添加到工作隊列中。這将喚醒正在等待任務的子程序,不過隻有一個子程序将獲得新任務的“接管權”,它可以從工作隊列中取出任務并執行之,而其他子程序将繼續睡眠在工作隊列上。
當選擇好子程序後,主程序還需要使用某種通知機制來告訴目标子程序有新任務需要處理,并傳遞必要的資料。最簡單的方式是,在父程序和子程序之間預先建立好一條管道,然後通過管道來實作所有的程序間通信。在父線程和子線程之間傳遞資料就要簡單得多,因為我們可以把這些資料定義為全局,那麼它們本身就是被所有線程共享的。

線程池主要用于:
1)需要大量的線程來完成任務,且完成任務的時間比較短。 比如WEB伺服器完成網頁請求這樣的任務,使用線程池技術是非常合适的。因為單個任務小,而任務數量巨大。但對于長時間的任務,比如一個Telnet連接配接請求,線程池的優點就不明顯了。因為Telnet會話時間比線程的建立時間大多了。
2)對性能要求苛刻的應用,比如要求伺服器迅速響應客戶請求。
3)接受突發性的大量請求,但不至于使伺服器是以産生大量線程的應用。