我尝试向 mio 添加一些 fd,包括 stdin。 我的应用程序在尝试从标准输入读取时卡住了,在我从 mio 获取事件后,该标准输入是可读的。
当我跟踪应用程序时,我注意到 mio 使用 epoll_wait
并且该系统调用立即返回。
strace -e trace=epoll_create,epoll_ctl,epoll_wait,read,epoll_create1 ./target/debug/ongybar
epoll_create1(EPOLL_CLOEXEC) = 6
epoll_ctl(6, EPOLL_CTL_ADD, 7, {EPOLLIN|EPOLLET, {u32=4294967295, u64=18446744073709551615}}) = 0
epoll_ctl(6, EPOLL_CTL_ADD, 3, {EPOLLIN, {u32=0, u64=0}}) = 0
epoll_ctl(6, EPOLL_CTL_ADD, 0, {EPOLLIN, {u32=0, u64=0}}) = 0
epoll_ctl(6, EPOLL_CTL_ADD, 4, {EPOLLIN, {u32=4, u64=4}}) = 0
epoll_wait(6, [{EPOLLIN, {u32=4, u64=4}}], 4, -1) = 1
read(4, "[...], 8192) = 1004
epoll_wait(6, [{EPOLLIN, {u32=0, u64=0}}], 4, -1) = 1
read(0,
我遇到此问题的完整代码位于 github .
最佳答案
我强烈猜测,不是 fd 0 (stdin) 而是 fd 3 变得可读: 这里
epoll_ctl(6, EPOLL_CTL_ADD, 3, {EPOLLIN, {u32=0, u64=0}}) = 0
epoll_ctl(6, EPOLL_CTL_ADD, 0, {EPOLLIN, {u32=0, u64=0}}) = 0
你可以看到,fd 0和3都注册到epoll_data u32/u64 = 0。
这里
epoll_wait(6, [{EPOLLIN, {u32=0, u64=0}}], 4, -1) = 1
你只能推断,两个注册的文件描述符 u32/u64=0 之一现在是可读的,但你无法在这里区分 fd 0 和 fd 3!由于从 stdin block 读取,它必须是 fd 3。
解决方案是为每个文件描述符使用 u32/u64 的唯一标识符,以便能够正确识别具有事件的正确文件描述符。
关于linux - rust mio 甚至在标准输入上也总是报告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44851378/