2013-07-10 58 views
6

我有一个多线程服务器进程,用C/C++编写,我试图用Google perftools进行配置。但是,当我使用perftools运行这个进程时,很快我的服务器停止了“系统调用中断”错误,我认为这是由传入的SIGPROF引起的。 (正在中断的实际系统调用在我呼叫zmq_recv的深处,但我认为它并不重要。)当我使用Google perftools时,SIGPROF杀死了我的服务器

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

回答

8

从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!)。

相关问题