Linux网络编程之socket编程(六)-SIGCHLD

上一次我们利用readline函数改进了回射客户/服务器,本次我们将进一步完善TCP回射客户/服务器,以及僵进程与SIGCHLD信号相关内容。

1.TCP回射客户/服务器

TCP回射客户/服务器完善

(1)上述第一个模型图中,并没有处理粘包问题。
(2)我们可以使用/n来区分消息与消息的边界。因此,实现第二个模型图更加合理。(上一篇博文已经总结了readn,writen以及readline的封装)

2.TCP是个流协议

(1)TCP是基于字节流传输的,只维护发送出去多少,确认了多少,没有维护消息与消息之间的边界,因而可能导致粘包问题。

(2)粘包问题解决方法是在应用层维护消息边界。

3.SIGCHLD信号与僵进程

SIGCHLD信号就是由内核在任何一个进程终止时发给它的父进程的一个信号。
设置僵死(zombie)状态的目的是维护子进程的信息,以便父进程在以后某个时候获取。这些信息包括子进程的进程ID、终止状态以及资源利用信息等等。

  • signal(SIGCHLD, SIG_IGN)
  • signal(SIGCHLD, handle_sigchld)

(1)当客户端关闭之后,服务器端还在维护着一个僵尸进程。对此,我们可以通过在服务器端加入如下代码,忽略SIGCHLD信号:
signal(SIGCHLD, SIG_IGN);

(2)另外一种方法是,我们可以捕捉SIGCHLD信号,来避免僵尸进程。

1)其中wait函数用来捕获子进程的状态,其中退出状态不关心就写为NULL

2)但是使用wait函数会有一个问题,如果有多个子进程同时退出,并不能去等待所有的子进程退出。因为wait仅仅等待第一个子进程退出就返回了。这个时候就需要用到waitpid函数。

(3)考虑如下示例:5个并发连接

1)客户端创建5个套接字与服务端相连。(为简单起见,下面代码只选择一个套接口sock[0]与服务端通信)。当客户端退出时,会有5个子进程都退出。
2)那么对服务端来说,开辟的5个子进程都向父进程发送了SIGCHLD信号。但是wait函数只等待一个子进程,其他4个子进程处于僵尸状态。多客户

3)针对这种情况就需要使用waitpid函数

其中,值-1表示等待第一个终止的子进程。WNOHANG选项表示,它告知内核在灭有已终止子进程时不要阻塞。

这样就避免了僵尸进程。

发表评论

电子邮件地址不会被公开。 必填项已用*标注