我有一个多线程服务器进程,用C/C++编写,我试图用Google perftools进行配置。但是,当我使用perftools运行这个进程时,很快我的服务器停止了“系统调用中断”错误,我认为这是由传入的SIGPROF引起的。 (正在中断的实际系统调用在我呼叫zmq_recv的深处,但我认为它并不重要。)当我使用Google perftools时,SIGPROF杀死了我的服务器
这是预期的行为吗?我应该以某种方式明确处理这个案件吗?或者这里出了问题?
我有一个多线程服务器进程,用C/C++编写,我试图用Google perftools进行配置。但是,当我使用perftools运行这个进程时,很快我的服务器停止了“系统调用中断”错误,我认为这是由传入的SIGPROF引起的。 (正在中断的实际系统调用在我呼叫zmq_recv的深处,但我认为它并不重要。)当我使用Google perftools时,SIGPROF杀死了我的服务器
这是预期的行为吗?我应该以某种方式明确处理这个案件吗?或者这里出了问题?
从zeroMQ文档zmq_recv(),我们可以预期,如果接收到信号时,它正在进行它返回EINTR
。
正在zmq_recv()
中间生成信号调用对于任何测试来说都是一项艰巨的任务。幸运的是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
*/
rc = 0;
while(rc != EINTR) {
rc = zmq_recv (socket, &part, 0);
}
而且install a signal handler function在你的程序。可以简单地忽略由于SIGPROF
而导致的中断并继续重试。
最后,您可能需要处理特定信号并采取相应措施。例如,即使用户按下CTRL + C正在等待您的程序正常终止,而您的程序正在等待zmq_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);
}
在代码保持“干净”的兴趣,你将得到更好的利用上面的代码中写身边zmq_recv()
自己static inline
功能的包装,你可以在你的程序中调用服务。
关于决定把zmq_recv()
回报EINTR
在接收信号时,你可能想结帐这篇文章是关于worse is better philosophy谈到这样的设计,是从实现的角度的视图简单的后面。
UPDATE:文件化代码来处理在zmq_recv()
上下文信号可在git.lucina.net/zeromq-examples.git/tree/zmq-camera.c。它与上面解释过的相同,但它看起来经过了充分的测试,并且随时可以使用详细评论(yayyy zeromq!)。