2017-06-20 63 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