在使用執行緒模型開發伺服器時需考慮以下問題:
1.調整程序內最大檔案描述符上限
2.執行緒如有共享資料,考慮執行緒同步
3.服務於客戶端執行緒退出時,退出處理。(退出值,分離態)
4.系統負載,隨著鏈結客戶端增加,導致其它執行緒不能及時得到cpu
多執行緒的機制一般是使用執行緒池,模型如下:
0;}以下是出錯處理的封裝,可以參考第五十篇部落格
/* wrap.c */
#include
#include
#include
/* 列印錯誤原因並退出 */
void perr_exit(const
char *s)
/* accept出錯封裝 */
int accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
return n;
}/* 繫結ip、埠號和socket,出錯則返回錯誤資訊 */
void bind(int fd, const
struct sockaddr *sa, socklen_t salen)
/* 客戶機連線伺服器函式封裝,錯誤則列印出錯資訊 */
void connect(int fd, const
struct sockaddr *sa, socklen_t salen)
/* listen函式出錯處理封裝 */
void listen(int fd, int backlog)
/* 建立套接字socket出錯處理封裝 */
int socket(int family, int type, int protocol)
/* read函式出錯處理封裝 */
ssize_t read(int fd, void *ptr, size_t nbytes)
return n;
}/* write函式出錯處理封裝 */
ssize_t write(int fd, const
void *ptr, size_t nbytes)
return n;
}/* close關閉檔案出錯處理封裝 */
void close(int fd)
/* 至少讀滿n個字元再返回 */
ssize_t readn(int fd, void *vptr, size_t n)
else
if (nread == 0)//訊號中斷 或 讀到空 則退出
break;
nleft -= nread;//記錄每次讀完,還剩的未讀的位元組數
ptr += nread; //為將下一次讀到的值補充到這次的末尾做準備
}return n - nleft; //返回已讀到的位元組數
}/* 寫滿n個字元才返回 */
ssize_t writen(int fd, const
void *vptr, size_t n)
nleft -= nwritten; //寫完這次之後,剩下還要寫的位元組個數
ptr += nwritten; //寫完這次之後,從這次的末尾繼續寫
}return n;
}/*返回第一次呼叫時字串的乙個字元,呼叫一次返回下乙個字元,供下面的函式呼叫*/
/* fd為要讀的檔案 ptr為要返回的字元(為傳出引數) */
static ssize_t my_read(int fd, char *ptr)
else
if (read_cnt == 0)//如果讀到的位元組數為0(即讀到的檔案為空)
return
0; /* 否則有讀到內容 則將讀指標指向該字串的首部 */
read_ptr = read_buf;
}//返回當前指向的字元,之後指向下乙個字元,供下一呼叫時使用
*ptr = *read_ptr++;
read_cnt--;//剩下待返回的字串的長度減一
return
1;//呼叫成功返回1
}/* 一次讀一行 */
ssize_t readline(int fd, void *vptr, size_t maxlen)
else
if (rc == 0)//如果讀完了就返回讀到的位元組數
else
return -1;
}*ptr = 0;
return n;
}
/* wrap.h */
#ifndef __wrap_h_
#define __wrap_h_
void perr_exit(const
char *s);
int accept(int fd, struct sockaddr *sa, socklen_t *salenptr);
void bind(int fd, const
struct sockaddr *sa, socklen_t salen);
void connect(int fd, const
struct sockaddr *sa, socklen_t salen);
void listen(int fd, int backlog);
int socket(int family, int type, int protocol);
ssize_t read(int fd, void *ptr, size_t nbytes);
ssize_t write(int fd, const
void *ptr, size_t nbytes);
void close(int fd);
ssize_t readn(int fd, void *vptr, size_t n);
ssize_t writen(int fd, const
void *vptr, size_t n);
static ssize_t my_read(int fd, char *ptr);
ssize_t readline(int fd, void *vptr, size_t maxlen);
#endif
測試方式可以參考第五十一篇客 併發伺服器模型 多執行緒伺服器
coding utf 8 from socket import from threading import thread from time import sleep 處理客戶端的請求並執行事情 def dealwithclient newsocket,destaddr while true rec...
高併發伺服器學習筆記之四 多執行緒模型
該模型和多程序模型的思想類似,只是把程序換成了執行緒,因為執行緒的建立比程序建立開銷小。但這並不是說多執行緒就一定比多程序優秀,程序和執行緒都有各自的優缺點,具體請自行查閱執行緒和程序相關的內容,完整 戳這裡 include include include include include inclu...
TCP的高併發伺服器模型
單客戶端單程序,統一accept 原型介紹 此併發伺服器模型並不預先分叉程序,而是主程序統一處理客戶端的連線,當客戶端的請求到達時,才臨時fork 程序,由子程序處理客戶端請求。利用socket 函式建立套接字,呼叫bind 函式繫結位址,呼叫listen 函式來監聽佇列長度,然後進入主處理過程,等...