Socket編程實踐(8) --TCP服務(wù)器常見問題(3)
來源:程序員人生 發(fā)布時間:2014-12-19 08:38:08 閱讀次數(shù):2518次
服務(wù)端多進程避免僵尸進程的方法
1)通過疏忽SIGCHLD信號,解決僵尸進程
在server端代碼中添加
signal(SIGCHLD, SIG_IGN);
2)通過wait/waitpid方法,解決僵尸進程
signal(SIGCHLD,onSignalCatch);
void onSignalCatch(int signalNumber)
{
wait(NULL);
}
Server端部份代碼:
//return a socket that have start listened.
int mkATCPServer(int serverPort, int backlog = SOMAXCONN)
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if (sockfd == ⑴)
{
err_exit("socket error");
}
//add address reused
int on = 1;
if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) == ⑴)
{
err_exit("setsockopt SO_REUSEADDR error");
}
//band a local address and port
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(serverPort);
serverAddr.sin_addr.s_addr = INADDR_ANY; //band an any IP address
if (bind(sockfd,(struct sockaddr *)&serverAddr,sizeof(serverAddr)) == ⑴)
{
err_exit("bind error");
}
//start to listen.
if (listen(sockfd,backlog) == ⑴)
{
err_exit("listen error");
}
return sockfd;
}
void onSignalCatch(int signalNumber)
{
waitpid(⑴,NULL,WNOHANG);
}
int main()
{
//安裝SIGCHLD信號處理函數(shù)
signal(SIGCHLD,onSignalCatch);
int serverSockfd = mkATCPServer(8002);
struct sockaddr_in peerAddr;
socklen_t peerLen = sizeof(peerAddr);
while (true)
{
//接受鏈接
int peerSockfd = accept(serverSockfd, (struct sockaddr *)&peerAddr,&peerLen);
if (peerSockfd == ⑴)
{
err_exit("accept error");
}
.....
//其他部份代碼與前面類似
多客戶端同時關(guān)閉問題
問題描寫以下:


客戶端代碼實現(xiàn)代碼
//其他代碼如前
//....
int main()
{
int serverSocket[10];
int socketCount = 10;
for (int i = 0; i < socketCount; ++i)
{
serverSocket[i] = mkATCPClient(8002,"127.0.0.1");
}
sleep(100);
return 0;
}
在客戶運行進程中按下Ctrl+C,則可以看到在server端啟動10個子進程,并且所有的客戶端全部1起斷開的情況下,產(chǎn)生的僵尸進程數(shù)是驚人的(此時也證明了SIGCHLD信號是不可靠的)!

解決方法:
//server端部份代碼以下:
//其他如前....
void onSignalCatch(int signalNumber)
{
int ret = 0;
//注意此處!!!!
while ((ret = waitpid(⑴,NULL,WNOHANG) != ⑴))
;
}
int main()
{
signal(SIGCHLD,onSignalCatch);
int serverSockfd = mkATCPServer(8002);
...
從下圖可以看出,出了監(jiān)聽server進程,已沒有僵尸進程了!

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學習有所幫助,可以手機掃描二維碼進行捐贈