2017-06-20 44 views
0

我從我的應用程序移除提升(因爲我想擺脫提升的同時,使用預先C++ 11)和相同的一部分,我遇到了以下問題。的sockfd在SIGINFO結構爲SIGIO信號

我有一段代碼,其連接,請求和異步使用boost(async_connect,ASYNC_WRITE和async_read呼叫)從遠程服務器接收數據。我打算用在異步模式下運行的linux本地套接字替換它。

對於相同的我開始看 ioctl(_sockfd,FIOASYNC,& on); 以異步模式設置套接字。 接着我還設置 的fcntl(_sockfd,F_SETOWN,GETPID()); 將所有與sockfd相關的信號發送到創建套接字的進程。處理SIGIO信號可訪問包含各種信號相關信息的siginfo_t結構。

但是我無法獲得從SIGINFO結構實例的sockfd收到這使得它很難破譯其中的sockfd; S SIGIO信號已經被抓住了。 si-> si_fd不匹配連接被調用的_sockfd。 爲什麼在SIGINFO確實的fd爲SIGIO犯規匹配指此信號產生所述的sockfd。 siginfo的內容是否可靠?

+2

我建議你忽略信號API並使用select()或poll()實現你的套接字處理,信號在多線程和麪向對象的設計中都不能很好地發揮作用,並且如果你需要異步套接字C++有一個很大的機會,你將需要兩個。 – gabry

+0

您是否在使用sigaction()建立信號處理程序時設置了'SA_SIGINFO'?另見https://stackoverflow.com/questions/19866754/sigio-arriving-for-file-descriptors-i-did-not-set-it-for-and-when-no-io-is-possi – nos

回答

0

socket(7)手冊頁:

Signals 
    ...[SIGPIPE para elided]... 

    When requested with the FIOSETOWN fcntl(2) or SIOCSPGRP ioctl(2), 
    SIGIO is sent when an I/O event occurs. It is possible to use 
    poll(2) or select(2) in the signal handler to find out which socket 
    the event occurred on. An alternative (in Linux 2.2) is to set a 
    real-time signal using the F_SETSIG fcntl(2); the handler of the real 
    time signal will be called with the file descriptor in the si_fd 
    field of its siginfo_t. See fcntl(2) for more information. 

    Under some circumstances (e.g., multiple processes accessing a single 
    socket), the condition that caused the SIGIO may have already 
    disappeared when the process reacts to the signal. If this happens, 
    the process should wait again because Linux will resend the signal 
    later. 

所以,

  • 使用實時信號,而不是與fcntl(sockfd, F_SETSIG, ...)
  • 使用非阻塞pollselect在你的信號處理器識別觸發fd,
  • ,只要使用在所述第一地點的正常同步複用(select/poll)。這是更正常的輸入法,並避免所有討厭的信號處理問題,但可能需要在事件循環周圍重構整個程序,所以...
0

POSIX aio?我個人從來沒有碰巧使用它,但也許這是你在找什麼。 https://linux.die.net/man/7/aio

另外,爲什麼你不喜歡boost::asioboost::threadboost::regexp和其他一些東西實際上是冗餘的在C++ 11/14,boost::filesystem是在C++ 17是多餘的。但標準庫不包含asio類似物。恕我直言,使用現成的,經過測試的,便攜式和廣泛傳播的解決方案比從頭開始編寫自己的解決方案更好。

+0

提升: :asio對我的用例來說實際上很重。提升IOService隊列過於通用,因此有開銷(每個poll_one都有互斥鎖和鎖)。所以我想擺脫它。 – user2496905