用于SIGIO信号的SIGINFO结构中的sockfd

时间:2017-06-20 12:43:06

标签: c++ sockets asynchronous boost struct

我正在从我的应用程序中删除boost(因为我想在使用pre c ++ 11时摆脱提升)并且作为同样的一部分我遇到了以下问题。

我有一段代码使用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与调用connect的_sockfd不匹配。 为什么SIGINFO中用于SIGIO的fd与生成此信号的sockfd不匹配。 siginfo的内容是否可靠?

2 个答案:

答案 0 :(得分: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)。这是更正常的IME,并且避免了所有令人讨厌的信号处理问题,但可能需要围绕事件循环重构整个程序,所以......

答案 1 :(得分:0)

POSIX aio怎么样?我个人从未碰巧使用它,但也许这就是你在寻找的东西。 https://linux.die.net/man/7/aio

另外,为什么你不喜欢boost::asioboost::threadboost::regexp以及其他一些事情在C ++ 11/14中实际上是多余的,boost::filesystem在C ++ 17中是多余的。但标准库并不包含asio类似物。恕我直言,最好使用现成的,经过测试的,便携式的,广泛传播的解决方案,而不是从头开始编写自己的解决方案。