SIGPIPE信号

昨天夜里实现了按行来切为数据包的协议, 今天就迫不及待使用resdis-benchmark来测试一下silly的性能。

结果发现到100000个请求左右时就有一定机率程序会默默的退出, 使用gdb看了一下, 是因为向socket写入数据时触发了SIGPIPE信号。

google了一下发现,当向一个已经关闭的socket第二次写入数据时,就会触发SIGPIPE。

但是我把所有的_socket_close都加了打印也没有发现问题。

最后偶然间发现,如果一个socket被对方关闭, 那么第一次write函数不一定返回出错, 但是第二次write却一定会触发SIGPIPE, 而SIGPIPE的默认行为则是退出运行。

假设Client和Server按如下顺序运行则会出现上述情况:
Client connect
Server accept
Client send
Server recv and process data
Client close
Server write result(此时write有一定机率依然会返回写入数据的长度,并不报错)
Server write result2(此时即会触发SIGPIPE信号, 导致程序退出)

因此在写socket程序, 如无特殊需要一定要使用signal(SIGPIPE, SIG_IGN)来忽略SIGPIPE信号, 不然这会是一个大坑。

发表评论

− 3 = three