我有一个multithreading服务器进程,用C / C ++编写,我试图用Google perftools进行configuration。 但是,当我用perftools运行这个进程时,很快我的服务器停止了一个“系统调用中断”错误,我认为这是由传入的SIGPROF引起的。 (正在中断的实际系统调用在我对zmq_recv的调用中很深 ,但是我不认为这是真正重要的。)
这是预期的行为? 我应该明确地处理这个案件吗? 还是在这里出了问题?
从zmq_recv()的zeroMQ文档中,如果在进行中接收到信号,我们可以期望它返回EINTR
。
在zmq_recv()
调用中间生成信号对于任何测试都是一项艰巨的任务。 幸运的是,产生大量SIGPROF
的gperftools在你的代码中发现了这个微妙的“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!)。