bro*_*s94 6 c c++ linux signals google-perftools
我有一个用C/C++编写的多线程服务器进程,我试图用Google perftools进行分析.但是,当我使用perftools运行该进程时,很快我的服务器因"syscall interrupt"错误而停止,我认为这是由传入的SIGPROF引起的.(正在被中断的实际系统调用深入到我对zmq_recv的调用中,但我认为它不是真正重要的.)
这是预期的行为吗?我应该以某种方式明确处理这个案子吗?或者这里出了什么问题?
从zmq_recv()的zeroMQ文档中,EINTR如果在进行中接收到信号,我们可以期望它返回.
在zmq_recv()通话中间生成信号对于任何测试都是一项艰巨的任务.幸运的是,生成大量s的gperftoolsSIGPROF在你的代码中发现了这个微妙的"bug".
这必须在您的代码中妥善处理,因为zeroMQ框架正在优雅地控制.重试逻辑可以像修改现有调用一样简单:
/* Block until a message is available to be received from socket */
rc = zmq_recv (socket, &part, 0);
Run Code Online (Sandbox Code Playgroud)
使用新的(具有重试逻辑)如下:
/* Block until a message is available to be received from socket
* Keep retrying if interrupted by any signal
*/
rc = 0;
while(rc != EINTR) {
rc = zmq_recv (socket, &part, 0);
}
Run Code Online (Sandbox Code Playgroud)
还要在程序中安装信号处理函数.人们可以简单地忽略由于中断而SIGPROF继续重试.
最后,您可能希望处理特定信号并采取相应措施.例如,即使用户在程序等待时按CTRL+ ,也可以正常终止程序.Czmq_recv()
/* Block until a message is available to be received from socket
* If interrupted by any signal,
* - in handler-code: Check for signal number and update status accordingly.
* - in regular-code: Check for status and retry/exit as appropriate
*/
rc = 0;
while(rc != EINTR && status == RETRY) {
rc = zmq_recv (socket, &part, 0);
}
Run Code Online (Sandbox Code Playgroud)
为了保持代码"干净",使用上面的代码片段编写自己的static inline函数包装器可以更好地服务zmq_recv(),您可以在程序中调用它.
关于在收到信号后做出zmq_recv()回报的决定EINTR,你可能想要查看这篇文章,谈论更糟糕的是这种设计背后更好的哲学,从实现的角度来看更简单.
更新:zmq_recv()在git.lucina.net/zeromq-examples.git/tree/zmq-camera.c上提供了用于处理上下文信号的文档化代码.它与上面解释的相同,但它看起来经过了很好的测试,随时可以使用详细的评论(yayyy zeromq!).