【发布时间】:2020-04-18 10:33:29
【问题描述】:
环境
- Linux x64
- Ubuntu 16.4
- C++
用例
- 异步 IO (epoll)
- 一个套接字用于读取和写入
- 读写操作不同步,在套接字上迭代完成
示例流程
- 设置套接字(EPOLL_CTL_ADD)
- 开始读取 (EPOLL_CTL_MOD + EPOLLIN | EPOLLONESHOT)
-
等待读取数据时
- [a] 写入一些数据(EPOLL_CTL_MOD + EPOLLOUT | EPOLLONESHOT)
问题描述
- 在上面的 #2 中注册了 EPOLLIN 读取操作
- 在 #3.a 中,EPOLLOUT 写入完成已注册在从套接字读取任何数据之前
- 鉴于上述情况,写完成操作@3.a 会取消挂起的读操作吗?
- 换句话说,假设 FD 最初是用没有设置 EPOLLIN 的 (EPOLL_CTL_MOD + EPOLLOUT) 调用的,将调用 EPOLL_CTL_MOD + EPOLLOUT erase 先前注册的 EPOLLIN 给定数据尚未准备好被读取??
上述情况的可能解决方法
- 是通过epoll_wait线程路由所有读/写操作来本地管理req IO状态,因此,而不是从任意线程调用EPOLL_CTL_MOD,确保它将始终从执行 epoll_wait 的同一线程中调用,在该线程中可以安全地维护 FD IO 状态 (EPOLLOUT/EPOLLIN)。
- 此解决方法的问题在于,它要求通过 epoll_wait 线程同步所有 IO 启动,这会导致额外的上下文切换,这可能会对性能产生不利影响...
这就是我想要弄清楚的:
有没有什么方法可以同步普通 FD 上的读/写 IO 操作而无需通过 epoll_wait 线程进行同步?有没有办法直接调用 EPOLL_CTL_MOD 而无需重置先前的状态?是否有任何线程安全的方式在已设置 EPOLLIN 的 FD 上添加 EPOLLOUT ?
【问题讨论】:
-
如果你可以读写两个不同的fd,你就可以用完全相同的过程读写同一个fd。只需使用 EPOLLIN|EPOLLOUT 设置一次套接字。
-
这是真的,但是,我需要处理 w 情况,例如。套接字(EPOLLIN)上有待处理的读取有效负载,并且没有提供要读取的缓冲区......并且要求我以线程安全的方式管理 FD 状态,因为它将被多个线程访问...... .如果可能的话,我想避免这种复杂性......打电话给例如。 EPOLL_CTL_MOD + POLLEIN 可以结合 w/ 提供缓冲区,POLLEOUT 也是如此......现在,当读取有效负载可用时,EPOLL_CTL_MOD 被称为 w POLLEIN | POLLEIN,但是,调用应用真的只对写入数据感兴趣......
-
有趣,我认为与EPOLL_CTL_DISABLE 相关,尽管它侧重于删除资源(以线程安全的方式)
-
你也可以
dup()socket FD,这样你就有2个不同的FD,每个都有自己的事件掩码。 -
是的,当然值得一试,我想知道我是否会在特定 FD 或两个副本上收到 epoll_wait 通知...我们会看到...
标签: c++ linux multithreading asynchronous epoll