欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

signal(SIGCHLD, SIG_IGN) 和 signal(SIGPIPE, SIG_IGN) 使用场景

程序员文章站 2022-07-14 09:53:48
...

一、signal(SIGCHLD, SIG_IGN);

因为并发服务器常常 fork 很多子进程,子进程终结之后需要服务器进程去 wait 清理资源。如果将此信号的处理方式设为忽略,可让内核把僵尸子进程转交给 init 进程去处理,省去了大量僵尸进程占用系统资源。(Linux Only)

对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在 Linux 下可以简单地将 SIGCHLD 信号的操作设为 SIG_IGN。

二、signal(SIGPIPE, SIG_IGN);

TCP 是全双工的信道,可以看作两条单工信道,TCP 连接两端的两个端点各负责一条。当对端调用 close 时,虽然本意是关闭整个两条信道,但本端只是收到 FIN 包,按照 TCP 协议的语义,表示对端只是关闭了其所负责的那一条单工信道,仍然可以继续接收数据。也就是说,因为 TCP 协议的限制,一个端点无法获知对端的 socket 是调用了 close 还是 shutdown。

对一个已经收到 FIN 包的 socket 调用 read 方法,如果接收缓冲已空,则返回 0,这就是常说的表示连接关闭。但第一次对其调用 write 方法时,如果发送缓冲没问题,会返回正确写入(发送)。但发送的报文会导致对端发送 RST 报文,因为对端的 socket 已经调用了 close,完全关闭,既不发送,也不接收数据。所以,第二次调用 write 方法(假设在收到 RST 之后),会生成 SIGPIPE 信号,导致进程退出。

为了避免进程退出,可以捕获 SIGPIPE 信号,或者忽略它,给它设置 SIG_IGN 信号处理函数:

signal(SIGPIPE, SIG_IGN);

这样,第二次调用 write 方法时,会返回 -1,同时 errno 置为 SIGPIPE。程序便能知道对端已经关闭。

 

转载于:https://blog.csdn.net/xinguan1267/article/details/17357093

 

(SAW:Game Over!)

相关标签: OS / Linux