网络模型:
通信进程为一个常驻内存进程,监听客户端的请求,当到达一个请求后,fork出一个子进程,做具体业务处理。
此时服务端对于recv函数的处理一般会是
sigset(SIGALARM, TimeOut);
alarm(time_out)
while(recv(...)<=0){
if(errno == EINTR)
continue;
else
return/break;
}
如果我们在TimeOut函数里面没有直接调用exit
,而此时服务端的recv又不断获得error==ENITR,则子进程会一直会在recv和中断信号处陷入死循环,子进程不会退出,可能会造成占用过高的CPU(比如父进程超时后后,然后客户端退出,此时子进程就会不断获得error==EINTR)
解决方法:
1.在超时处理函数中直接调用exit,这样的话子进程的套接字不能及时的close(可以使用setjmp保存堆栈信息,同时在超时处理函数中使用longjmp跳回到保存的堆栈信息关闭套接字);
2.在while处增加循环次数的判断,比如超过5次子进程退出。