2013-07-10 56 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!)。

相關問題