signal(SIGCHLD, SIG_IGN) 和 signal(SIGPIPE, SIG_IGN)

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。程序便能知道对端已经关闭。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值