环境

  • Linux x64
  • Ubuntu 16.4的
  • C++

  • 用例
  • 异步IO(epoll)
  • 一个套接字用于读写
  • 读和写操作,并且不同步,并且是在套接字
  • 上迭代完成的

    sample 流量
  • 设置套接字(EPOLL_CTL_ADD)
  • 开始阅读(EPOLL_CTL_MOD + EPOLLIN | EPOLLONESHOT)
  • 在等待读取数据时
  • [a] 写一些数据(EPOLL_CTL_MOD + EPOLLOUT | EPOLLONESHOT)

  • 问题描述
  • 在EPOLLIN读取操作上方的#2处注册了
  • 在#3.a处,从套接字读取任何数据之前,已在中注册了EPOLLOUT写完成
  • 鉴于以上所述,写入完成操作@ 3.a是否会取消挂起的读取操作?
  • 换句话说,假设最初使用未设置EPOLLIN的(EPOLL_CTL_MOD + EPOLLOUT )调用FD,则将调用EPOLL_CTL_MOD + EPOLLOUT 擦除,因为尚未准备好读取数据,因此先前注册的EPOLLIN是?

  • 上面的一种可能的解决方法
  • 通过通过epoll_wait线程路由所有读/写操作来本地管理req IO状态,因此,而不是从任意线程调用EPOLL_CTL_MOD,请确保始终从执行FD的epoll_wait的同一线程中调用它可以安全地保持IO状态(EPOLLOUT/EPOLLIN)。
  • 此解决方法的问题是它要求通过epoll_wait线程同步所有IO启动,并且会导致额外的上下文切换,这可能会对性能产生不利影响...

  • 那就是我要弄清楚的:

    有没有什么方法可以同步通用FD上的读/写IO操作,而无需通过epoll_wait线程进行同步?有什么方法可以直接调用EPOLL_CTL_MOD而不重置先前的状态?在已经设置了EPOLLIN的FD上添加EPOLLOUT有没有线程安全的方式

    最佳答案

    如此...就像@Hasturkun所建议的那样,使用dup过滤EPOLLIN和EPOLLOUT事件(以线程安全的方式)达到了目的,但是,对我来说,这看起来更像是一种破解/解决方法...我觉得很尴尬没有更好的解决方案... Windows IOCompletion端口对我来说似乎更优雅...

    10-04 21:11