unpv3上一共總結了9種伺服器模型分別是:
1.迭代伺服器
2.併發伺服器,為每個客戶fork乙個程序
3.預先派生子程序,每個子程序都呼叫accept,accept無上鎖保護
4.預先派生子程序,以檔案鎖的方式保護accept
5.預先派生子程序,以執行緒互斥鎖上鎖的方式保護accept
6.預先派生子程序,由父程序向子程序傳遞套介面描述字
7.併發伺服器,為每個客戶請求建立乙個執行緒
8.預先建立執行緒,以互斥鎖上鎖方式保護accept
9.預先建立執行緒,由主線程呼叫accept,並把每個客戶連線傳遞給執行緒池中某個
可用執行緒
1.迭代伺服器
典型**:
socket
bind
listen
for(;;)
優點:主要是程式設計簡單
缺點:處理完乙個連線之後才能處理下乙個連線,無併發可言,應用很少
2.併發伺服器,為每個客戶fork乙個程序
典型**:
init_address(server_addr)
listenfd = socket(af_inet,socket_stream,0);
bind(listenfd, (sa*)server_addr, sizeof(serveraddr));
listen(listenfd,backlog);
for(;;)
if(fork() == 0)
close(connfd);//parent, close connected socket }
早起的網路伺服器每天處理幾百或者幾千個客戶連線時,這種伺服器模型還是可以應付的。
但是隨著網際網路業務的迅猛發展,繁忙的web伺服器每天可能需要處理千萬以上的連線,
並 發伺服器的問題在於為每個客戶現場fork乙個子程序比較消耗cpu時間。
3.預先派生子程序,每個子程序都呼叫accept,accept無上鎖保護
缺點:1.
伺服器必須在啟動的時候判斷需要預先派生多少子程序
2.驚群現象(乙個連線到來喚醒所有監聽程序)
,不過較新版本的linux貌似修正了這個問題
優點:無須引入父程序執行fork的開銷就能處理新到的客戶
4.預先派生子程序,以檔案鎖的方式保護accept
本模型與3的區別僅僅是對accept(listenfd)使用了檔案鎖.
這種模型是為了解決以庫函式的形式實現的accept不能在多個程序中引用同乙個監聽套介面的
問題(源自bsd的unix,在核心中實現的accept可以引用)。
使用檔案鎖保證了每個連線到來,只
有乙個程序阻塞在accept呼叫上
。 對於已經在核心中實現了accept的系統來說,
這種模型至少增加了加鎖解鎖的開銷
,所以相對於
第3種模型效能較低(特別是在消除了驚群問題的系統上)
5.預先派生子程序,以執行緒互斥鎖上鎖的方式保護accept
典型**:
static pthread_mutex_t *mptr;
void
my_lock_init(char *pathname)
void
my_lock_wait()
void
my_lock_release()
intmain(int argc, char **ar**)
for(;;)
pause(); }
pid_t
child_make(int i, int listenfd, int addrlen)
void
child_main()
} 這種模型在模型4上做出了進一步的改進,
由於以檔案鎖的方式實現保護會涉及檔案系統,這樣
可能比較耗時,
所以改進的辦法是以pthread mutex互斥量代替檔案鎖。使用執行緒上鎖保護accept
不僅適用於同一程序內各執行緒上鎖,也適用於不同程序間上鎖
在多程序環境下使用執行緒互斥鎖實現同步有兩點要求: 1
.互斥鎖必須放在由所有程序共享的記憶體區
2.必須告知執行緒庫這是在不同的程序間共享的互斥鎖
注意:目前很火的高效能web伺服器的代表nginx就是採用的這種模型,網路上對nginx的研究很多。
6.預先派生子程序,由父程序向子程序傳遞套介面描述字
優勢:不需要對accept上鎖保護
劣勢:1.
編碼複雜—父程序必須跟蹤子程序的忙閒狀態,以便給空閒子程序傳遞新的套介面
。在前述的
預先派生子程序的例子中,父程序無需關心由哪乙個子程序接收乙個客戶連線,作業系統會根據排程
演算法處理這些細節。採用這種模型的結果是這些程序無法均衡的處理連線。
2.父程序通過
位元組流管道
把描述子傳遞到各個子程序,並且各個子程序通過位元組流管道寫回單個
位元組,比起無論是使用共享記憶體區中的互斥鎖還是使用檔案鎖實施的上鎖和解鎖都更費時。
7.併發伺服器,為每個客戶請求建立乙個執行緒
典型**:
for(;;)
void *
doit(void *arg)
優點:編碼簡單
缺點:現場為每個連線建立執行緒相對於預先派生執行緒池來說比較耗時
8.預先建立執行緒,以互斥鎖上鎖方式保護accept
優勢 1.程式設計簡介,易於理解
2.執行緒池的方式避免了現場建立執行緒的開銷
3.os執行緒排程演算法保證了執行緒負載的均衡性
這就是leader-follower模式
乙個執行緒等待連線到來,其他執行緒休眠;新連線到來後leader去處理連線,釋
放listenfd,其他執行緒競搶監聽套介面listenfd(可能有驚群的問題)。leader在處理完連線以後成為follower
9.預先建立執行緒,由主線程呼叫accept,並把每個客戶連線傳遞給執行緒池中某個
可用執行緒
劣勢:相對於模型8,該模型不僅需要使用pthread mutex額外還需要使用pthread cond
伺服器模型
伺服器模型 1 迴圈伺服器模型 tcp 迴圈伺服器 udp 迴圈伺服器 2 併發伺服器 tcp 併發伺服器 父子程序實現併發伺服器 父親程序 接收請求。accept 兒子程序 處理具體客戶端需求。send recv 注意點 殭屍程序,父親活著,兒子死亡,父親沒有為兒子程序收屍,會產生殭屍程序。避免殭...
伺服器模型
在使用socket進行網路程式設計時,首先要選擇乙個合適的伺服器模型是很重要的。在網路程式裡,通常都是乙個伺服器服務多個客戶機,為了處理多個客戶機的請求,伺服器端的程式有不同的處理方式。迭代模型算是最早期的伺服器模型,其核心實現是每來乙個使用者,然後為這個使用者服務到底,過程中不接受任何新的使用者請...
TCP伺服器模型
迴圈伺服器 迴圈伺服器在同乙個時刻只可以響應乙個客戶端的請求 併發伺服器 併發伺服器在同乙個時刻可以響應多個客戶端的請求 9.1 迴圈伺服器 udp伺服器 udp迴圈伺服器的實現非常簡單 udp伺服器每次從套接字上讀取乙個客戶端的請求,處理,然後將結果返回給客戶機.可以用下面的演算法來實現.sock...