📔【操作系统】I/O 多路复用,select / poll / epoll 详解 #79
Replies: 21 comments 2 replies
-
博主,请问这个调用select需要将所有文件描述符传到内核空间里面仅仅是为了安全考虑吗? |
Beta Was this translation helpful? Give feedback.
-
需要将文件描述符传到内核,是因为 Select 是一个系统调用,系统调用会陷入内核,所以必须从用户态拷贝文件描述符到内核态。也就是说,“拷贝到内核空间”是“运行在内核态”的必然产物。 但内核态本身就是为了系统安全考虑 —— 只有在内核态下才能执行 I/O 等受限指令 (参考这篇文章)。“拷贝到内核空间”和”系统安全”不是因果关系,而是后者的必要不充分条件。 |
Beta Was this translation helpful? Give feedback.
-
可是内核态不是可以访问完整的地址空间吗?只需要一个系统调用执行切换到内核态(运行在内核空间)告诉内核某一块地址的东西需要进行扫描就可以了不是吗 |
Beta Was this translation helpful? Give feedback.
-
@jiutai 查了一下,本质还是处于安全原因考虑,禁止在内核空间直接对用户空间的指针解引用。 原因有以下几个:
参考: |
Beta Was this translation helpful? Give feedback.
-
博主有心了,受教了,感谢解惑! |
Beta Was this translation helpful? Give feedback.
-
@jiutai 客气了,你这个问题我之前确实没想过,也是开阔思路了。期望多多交流。 |
Beta Was this translation helpful? Give feedback.
-
https://zhuanlan.zhihu.com/p/371478926 似乎有人转载了你的文章的但是没有写引用? |
Beta Was this translation helpful? Give feedback.
-
@LydiaCai1203 我这么小众的博客都有人抄去卖课就离谱… 我问问他 |
Beta Was this translation helpful? Give feedback.
-
hello 又是我。 文章中关于 然后我查看了 linux 的文档。 其中关于 int poll(struct pollfd *fds, nfds_t nfds, int timeout); 关于 struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
}; 代码看上去还是数组存储,不是链表存储。 |
Beta Was this translation helpful? Give feedback.
-
你的描述是对的,之前我写的时候也没有探究,已经改过来了。非常感谢指出错误!不然又要误导很多同学了。 |
Beta Was this translation helpful? Give feedback.
-
言重了。我看你的文章也理清楚了之前没理清楚的知识~ 也非常感谢你的文章~~ |
Beta Was this translation helpful? Give feedback.
-
博主,总结那块poll还是写的用链表存储,没改过来 |
Beta Was this translation helpful? Give feedback.
-
谢谢指出,改过来了 |
Beta Was this translation helpful? Give feedback.
-
博主,读文章的时候我有这么个疑问,select, poll 和 epoll 在超时时间到达时或者有某个 fd 就绪后就会返回,随后用户进程执行具体的读写任务,但那些用户进程关心,但是还没有就绪的 fd 会怎么样呢?需要用户进程执行下次 select, poll 或 epoll 系统调用时再添加一遍么? |
Beta Was this translation helpful? Give feedback.
-
没有就绪的 fd,不会怎么样,还是在等待就绪事件的发生。这都是操作系统处理的,用户进程不需要关心。 对于 select、poll,每次执行,都需要传递所有的要检查是否就绪的 fd 集合。select、poll 内部不会缓存用户进程之前调用的时候传递进来的 fd。这也是 select、poll 的缺点。 epoll 只需要传递一次 fd,操作系统负责缓存这个 fd,然后在其就绪时通知用户进程。如果 fd 还没就绪,但是用户进程已经不关心它了,可以通过 |
Beta Was this translation helpful? Give feedback.
-
博主,请问在LT和ET中,我对LT到来的可读事件进行和ET一样的操作,也把数据一次性读完,这样也减少事件的触发次数,所以LT在这种操作的情况下,是不是和ET的性能一样呢? |
Beta Was this translation helpful? Give feedback.
-
从定义看,处理流程应该是一致的 —— 都是通知了一次。不过性能上,还没有深入研究,得看内部咋实现了。我们使用的话,这方面差异应该不大。 关于这个,可以写个 demo 验证下。https://juejin.cn/post/6844903878685622285 是一个例子。 |
Beta Was this translation helpful? Give feedback.
-
链表存储貌似没有错 数组也没有错 用户态是数组 陷入内核态会转换成链表 |
Beta Was this translation helpful? Give feedback.
-
赞啊!之前从没注意过 |
Beta Was this translation helpful? Give feedback.
-
楼主您好,谢谢您的分享,我有点疑惑想请教:ET模式会漏掉某些fd怎么处理 以及 怎么判断是什么fd有事件发生,之后是怎么工作的 |
Beta Was this translation helpful? Give feedback.
-
博主,说实话,感觉你的这篇文章说了跟没说差不多,属于那种懂的人看了也没用,不懂的人看了也还是不懂,比如我就是看了也不是不懂。 关于 epoll 优点总结的那一段: 对于“性能开销大”,epoll_ctl 中为每个文件描述符指定了回调函数,并在就绪时将其加入到就绪列表,因此 epoll 不需要像 select 那样遍历检测每个文件描述符,只需要判断就绪列表是否为空即可。这样,在没有描述符就绪时,epoll 能更早地让出系统资源。 这里面提到的“回调函数”,到底是个什么原理? 当然你写什么是你的自由,我是从一个对读者有用的出发点来写下这条评论。做为一名编程人员,我觉得写技术博客还是严谨些吧,不然浪费了读者的时间。 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
https://imageslr.github.io/2020/02/27/select-poll-epoll.html
简介 阻塞 I/O 与非阻塞 I/O: 阻塞 I/O,即进程发起调用后,会被挂起(阻塞),直到收到数据再返回。缺点:如果调用一直不返回,进程就会一直被挂起 非阻塞 I/O 不会将进程挂起,调用时会立即返回成功或错误,优点是如果调用一直不成功,进程可以主动放弃这次调用,执行别的操作。缺点是非阻塞 I/O 需要不断轮询返回值,直到返回成功,这样效率很低
Beta Was this translation helpful? Give feedback.
All reactions