高效能伺服器程式設計 程序池 執行緒池

2021-09-25 18:01:11 字數 3219 閱讀 5823

高效能伺服器程式設計主要分為多程序和多執行緒、程序池和執行緒池,用來處理乙個服務程式能夠同時處理多個客戶連線的問題。我們首先回顧下多程序和多執行緒的知識,因為程序池和執行緒池是在這個基礎上進行改進的,也是伺服器用的比較多的。   

多程序

accept();  --》建立子程序,由子程序和客戶端通訊。父程序繼續接受客戶連線

a.子程序繼承父程序開啟的檔案描述符(accept返回的檔案描述符)

b.父程序必須關閉檔案描述符。

2.多執行緒

accept();  --》建立函式執行緒,由函式執行緒和客戶端通訊,主線程繼續接受客戶連線

a.主線程接受客戶連線的檔案描述符如何傳遞給函式執行緒 –》值傳遞

b.主線程不能關閉檔案描述符  ---》 程序的pcb中儲存 同程序的多執行緒共享乙個pcb

應用場景:

:提前申請的大量資源存放的乙個單位;

記憶體池:  使用記憶體之前,先申請大量的記憶體,當後續需要使用時,直接從記憶體池中分配,不需要通過系統分配。

多程序和多執行緒與執行緒池和程序思想對比:

我們看下我們linux下池中最多有幾個程序:

由此可看有8個程序,通常池中分配大約的3---10個。執行緒池我們也看一下:

可看出也是有8個,其實在選擇程序池還是執行緒池,也是根據我們的業務和環境的要求下進行選擇。例如如果考慮安全性可以使用程序池,如果考慮切換速度,資料共享的話可以考慮執行緒池,各有各有好處和應用場景,更適合才是最重要的~

我們通過**再來看看執行緒池有些什麼問題。在這之前,我們要明白執行緒池實現的幾個難點:

主線程需要將檔案描述符傳遞給函式執行緒  --》全域性的陣列

函式執行緒啟動起來必須阻塞在獲取檔案描述符之前 --》訊號量

訊號量來控制主線程向函式執行緒通知獲取檔案描述符事件  --》訊號量

主線程在陣列中插入資料,以及函式執行緒獲取陣列中的資料都必須是互斥的,保持原子操作。  ---》互斥鎖

//-1是無效的檔案描述符

}int main()

initclilink(); //初始化值

sem_init(&sem,0,0);

pthread_mutex_init(&mutex,null);

while(1)

if(insert(c) == -1)

//對訊號量的v操作

sem_post(&sem); }}

void *pthread_fun(void *arg)

while(1) //與特定的客戶端通訊

; int n = recv(c,buff,127,0);

if(n <= 0)

printf("%d: %s\n",c,buff);

send(c,"ok",2,0);

} }}

結果如下:

因為我只維護了三個執行緒,因此當我開啟第四個客戶端的時候,它會在阻塞的狀態,當我關閉前三個任意乙個程序時,會發現它立刻可以執行。比如說關閉third客戶端。

可以看出four立即就被列印了~~

int getcli()

clilink[i] = -1;

pthread_mutex_unlock(&mutex);

if(i >= 10)

return -1;

return c;

//-1是無效的檔案描述符

}

在程式啟動時,建立多個程序,將子程序維護在程序池;

程序池中的程序必須阻塞在獲取到客戶端檔案描述符之前;

主程序負責接收客戶連線,並將獲取到的客戶連線檔案描述符傳遞給程序池中的程序

必須借助於程序間通訊不能僅僅傳遞c值,傳遞的是檔案描述符--》指向相同的結構

如何在兩個不相干的程序之間傳遞檔案描述符呢? 我們可以利用socket在程序間傳遞特殊的輔助資料,以實現檔案描述符的傳遞。另外我們還可以結合socketpair全雙工管道,以及函式sendmsg  、recvmsg等相關知識學習下程序池的**。有興趣的小夥伴可以看看《linux高效能服務程式設計》裡的程序的**實現~

兩者的選擇和多程序和多執行緒一樣,需要因情況和場景選擇。我們要明白乙個執行緒或者執行緒開始為乙個客戶端服務時,只能等客戶端退出才能服務下乙個客戶端,對於執行緒資源是一種浪費。阻塞在recv函式。但是i/o復用可以解決同時處理與多個客戶端互動的問題。

高效能伺服器程式設計 程序池或執行緒池

一般來說,伺服器的硬體資源相對充裕,很多時候都用空間換時間的方法來提高伺服器的效能,不惜浪費大量的空間資源來換取伺服器的執行效率。具體做法 提前申請大量的資源,以備不時之需以及重複使用。這就是池的概念 池其實就是一組資源的集合。靜態資源分配 這組資源在伺服器啟動之初,就已經被建立並初始化 動態資源分...

高效能伺服器程式設計 執行緒池

在我們之前所講述過的以poll方式實現tcp伺服器流程,我們仔細研究一下會發現,客戶端的資料我們還是以序列的方式來處理的。由此我們提出了以多程序或者多執行緒的方式來加以實現是不是會更好。比如採用多程序的方式 但是這種方式還是會有bug出現,比如有僵死程序的情況出現和建立程序的代價很大等情況發生。此處...

執行緒池實現高效能伺服器

為了改善多程序和多執行緒實現伺服器不停地建立刪除程序或執行緒給系統帶來的負擔,引進了執行緒池,程序池來改善此種情況,此處以執行緒池為例。執行緒池的優勢 1 建立的程序或者執行緒是有限的,伺服器的系統代價比較小,一般不會到達系統限制的值。2 伺服器不需要頻繁的建立 銷毀程序或者執行緒,只在伺服器啟動時...