使用谷歌perftools时,SIGPROF杀死我的服务器

我有一个multithreading服务器进程,用C / C ++编写,我试图用Google perftools进行configuration。 但是,当我用perftools运行这个进程时,很快我的服务器停止了一个“系统调用中断”错误,我认为这是由传入的SIGPROF引起的。 (正在中断的实际系统调用在我对zmq_recv的调用中很深 ,但是我不认为这是真正重要的。)

这是预期的行为? 我应该明确地处理这个案件吗? 还是在这里出了问题?

zmq_recv()的zeroMQ文档中,如果在进行中接收到信号,我们可以期望它返回EINTR

zmq_recv()调用中间生成信号对于任何测试都是一项艰巨的任务。 幸运的是,产生大量SIGPROFgperftools在你的代码中发现了这个微妙的“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 */ rc = 0; while(rc != EINTR) { rc = zmq_recv (socket, &part, 0); } 

还要在程序中安装信号处理函数 。 可以简单地忽略由于SIGPROF引起的中断,并继续重试。

最后,您可能需要处理特定的信号并采取相应的行动。 例如,即使用户在程序在zmq_recv()上等待时按下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 */ rc = 0; while(rc != EINTR && status == RETRY) { rc = zmq_recv (socket, &part, 0); } 

为了保持代码“干净”,通过使用上面的代码片段来编写自己的static inline函数包装函数zmq_recv()可以在程序中调用zmq_recv() ,可以更好地服务代码。

关于zmq_recv()在接收到信号时返回EINTR的决定,您可能希望结束这篇文章,谈论更糟糕的是这样一个设计背后更好的哲学 ,从实现的角度来看更简单。


更新 :记录在zmq_recv()上下文中处理信号的代码可在git.lucina.net/zeromq-examples.git/tree/zmq-camera.c中找到 。 它与上面解释的一样,但看起来很好测试,随时可以用详细的评论洒满(yayyy zeromq!)。