我有一個多線程服務器進程,用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!)。