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

SIGPROF kills my server when using google perftools

本文关键字:我的 服务器 perftools 谷歌 SIGPROF      更新时间:2023-10-16

我有一个用C/C++编写的多线程服务器进程,我正试图用Google perftools对其进行评测。然而,当我使用perftools运行该进程时,很快我的服务器就会因"系统调用中断"错误而停止,我认为这是由传入的SIGPROF引起的。(被中断的实际系统调用在我对zmq_recv的调用中很深,但我认为它是哪一个并不重要。)

这是预期的行为吗?我应该以某种方式明确处理这个案件吗?还是这里出了什么问题?

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

zmq_recv()调用中间生成信号对于任何测试来说都是一项艰巨的任务。幸运的是,gperftools生成了大量的CCD_;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引起的中断并继续重试。

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

为了保持代码";"干净";,使用上面的代码段围绕zmq_recv()编写自己的static inline函数包装器会更好地为您服务,您可以在程序中调用它。

关于让zmq_recv()在接收到信号时返回EINTR的决定,您可能需要查看本文,该文章讨论了从实现角度来看更简单的设计背后的越差越好的哲学


UPDATE:在zmq_recv()的上下文中处理信号的文档化代码可在git.locina.net/zeromq examples.git/tree/zmq camera.c中找到。它与上面解释的内容相同,但它看起来经过了很好的测试,可以随时使用,详细的注释随处可见(yayyy zeromq!)。