C++ SIGPROF在使用google perftools时杀死我的服务器
我有一个用C/C++编写的多线程服务器进程,我正试图用Google perftools分析它。但是,当我使用perftools运行该进程时,很快我的服务器就会因“syscallinterrupted”错误而停止,我认为这是由传入的SIGPROF引起的。(被中断的实际系统调用深入到我对的调用中,但我认为它是哪一个并不重要。)C++ SIGPROF在使用google perftools时杀死我的服务器,c++,c,linux,signals,google-perftools,C++,C,Linux,Signals,Google Perftools,我有一个用C/C++编写的多线程服务器进程,我正试图用Google perftools分析它。但是,当我使用perftools运行该进程时,很快我的服务器就会因“syscallinterrupted”错误而停止,我认为这是由传入的SIGPROF引起的。(被中断的实际系统调用深入到我对的调用中,但我认为它是哪一个并不重要。) 这是预期的行为吗?我应该以某种方式明确地处理这个案子吗?还是这里出了什么问题?从zeroMQ的文档中,我们可以预期,如果在处理过程中收到信号,它将返回EINTR 在代码> Z
这是预期的行为吗?我应该以某种方式明确地处理这个案子吗?还是这里出了什么问题?从zeroMQ的文档中,我们可以预期,如果在处理过程中收到信号,它将返回
EINTR
在<强>代码> ZMQJRCVE()中产生信号,调用对于任何测试来说都是一项艰巨的任务。幸运的是,gperftools生成了大量的
SIGPROF
s,从而在代码中发现了这个微妙的“bug”
由于zeroMQ框架正在优雅地放弃控制权,因此必须在代码中优雅地处理。重试逻辑可以像修改现有调用一样简单:
/* Block until a message is available to be received from socket */
rc = zmq_recv (socket, &part, 0);
使用新的一个(具有重试逻辑),如下所示:
/* Block until a message is available to be received from socket
* Keep retrying if interrupted by any signal
*/
do {
rc = zmq_recv (socket, &part, 0);
} while(errno == EINTR);
也在你的节目里。您可以简单地忽略由于SIGPROF
引起的中断,然后继续重试
最后,您可能需要处理特定的信号并相应地采取行动。例如,在程序等待时,即使用户按下CTRL+C,也可以优雅地终止程序
/* 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
*/
do {
rc = zmq_recv (socket, &part, 0);
} while(errno == EINTR && status == RETRY);
为了保持代码“干净”,您可以使用上面的代码片段编写自己的静态内联函数包装器,将zmq_recv()
封装在程序中调用
关于在接收信号时返回EINTR的决定,您可能想查看这篇文章,它讨论了这种从实现角度来看更简单的设计背后的原因
更新:在zmq_recv()的上下文中处理信号的文档化代码可在上找到。它与上面解释的内容相同,但是它看起来经过了很好的测试,可以随时使用,并且有详细的注释(yayyy zeromq!)。条件应该是while(errno==EINTR),而不是while(rc!=EINTR)。更新了代码片段。感谢您的代码审阅!:-)