1.阻塞与某个慢系统调用的进程捕获信号并返回,该系统调用可能返回EINTR错误。
正确处理慢系统调用 :
for ( ; ; ) {
clilen = sizeof(cliaddr);
if ( ( conndf = accpet(listenfd, (SA *)&cliaddr, &clilen) < 0 ) ) {
if ( errno == EINTR ) {
continue;
} else {
err_sys("accept error");
}
}
}
2.Unix中信号不一般不排队,信号处理函数一般只执行一次。
使用 waitpid(), 而不是 wait。waitpid 函数,指定 WNOHANG 选项,如果有
尚未终止的子进程运行时,不要阻塞。
3.编写网络程序时,可能会遇到的3种情况:
1.当fork子进程时,必须捕获 SIGCHILD 信号;
2.当捕获信号时,必须处理被中断的系统调用;
3.SIGCHILD 的信号处理函数必须被正确编写,应该使用waitpid函数以免留下僵死进程。
4.服务器进程被终止
服务器一段先发送FIN,如果客户端再发送数据,服务器会返回一个RST,
如果客户端read在接受 RST 之前,客户端收到一个未预期的EOF(服务器过早终止)。
如果客户端read在接受到 RST 之后,read 返回一个 ECONNREST,"connection reset by peer", 对方复位连接错误。
5.服务端进程已经发送FIN,第一次写引发 RST。 再次写,引发 SIGPIPE 信号
6.如果服务器主机奔溃,客户端阻塞在read上,超过一定时间返回 timeout 超时或者主机不可达错误。
这是主动发送错误才发现的,还有另外的技术。SO_KEEPALIVE套接字选项。
void sig_child(int signo)
{
pid_t pid;
int stat;
while ( (pid = waitpid(-1,&stat,WNOHANG)) > 0 ) { // 循环获取已经终止子进程的状态, WNOHANG如果有尚未终止的子进程,不阻塞
printf("child %d terminated \n",pid);
}
return;
}
1.概述
处理 SIGCHLD 信号
wait 和 waitpid 函数
accpet 返回前终止:
服务器进程终止:
SIGPIPE 信号:
服务器主机崩溃:
服务器主机崩溃后重启: