Unix/linux 编程实践教程 ---------- 服务器-客户端编程

一个简单到服务器可以写成这个样子:


int main()
{
	int sock,fd;
	void child_waiter(int),process_request(int);
	signal(SIGCHLD,child_waiter);
	if((sock=make_server_socket(PORTNUM)) == -1)
		err_deal("---");
	
	while(1)
	{
		if(fd = accept(sock,NULL,NULL) == -1)
		{
			if(errno == EINTR)			//  第一处
				continue;
			else
				break;
		}

		process_request(fd);
		close(fd);
	}
}

void child_waiter(int s)
{
	while(waitpid(-1,NULL,WNOHANG) > 0);			//第二处
}

void process_request(int fd)
{
	---------
}

第一处:
    为什么需要处理 accept 可能产生到 EINTR 错误呢, 因为这个errno可能是因为信号 SIGCHLD产生的,信号的产生会转到信号处理函数从而中断accept,从而导致accept返回-1,并设置 errno为 EINTR,如果不处理,就无法区分到底是真正到错误还是信号SIGCHLD的产生导致的-1的返回了。

第二处:
    这是关于如何处理多个信号的。如果多个子进程几乎同时退出,将会如何呢?
    假设同时有3个SIGCHLD发到父进程。最先到的信号导致父进程着手处理该信号,其余信号导致信号阻塞,但是并不缓存信号。从而第二个信号阻塞,而第三个信号丢失。此时,如果还有其他子进程退出,那这些信号也会丢失。
    解决办法是调用wait足够多次来去除所有的终止进程,因此要用while 多次调用waitpid
        waitpid第一个参数 -1 表示等待所有的子进程,第二个NULL表示子进程到状态,第三个WNOHANG表示如果没有僵尸进程则不必等待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值