我正在使用 epoll/devpoll/kqueue/poll/select(包括 windows-select)为异步套接字 IO 设计事件循环。
我有两个执行 IO 操作的选项:
非阻塞模式,在 EAGAIN 上轮询
- 将套接字设置为非阻塞模式。
- 读/写套接字。
- 如果操作成功,将完成通知发布到事件循环。
- 如果我得到 EAGAIN,将套接字添加到“选择列表”并轮询套接字。
轮询方式:先轮询再执行
- 将套接字添加到选择列表并对其进行轮询。
- 等待可读可写的通知
- 读/写
- 将完成通知发布到成功种子的事件循环
在我看来,在正常模式下使用时,首先需要较少的系统调用, 特别是对于写入套接字(缓冲区非常大)。 而且看起来可以减少“选择”数量的开销 执行,特别是当你没有很好扩展的东西时它很好 作为 epoll/devpoll/kqueue。
问题:
- 第二种方法有什么优势吗?
- 在众多操作系统(Linux、FreeBSD、Solaris、MacOSX、Windows)上,套接字/文件描述符的非阻塞操作是否存在任何可移植性问题。
注意:请不要建议使用现有的事件循环/套接字 API 实现
最佳答案
我不确定是否存在任何跨平台问题;至多您必须使用 Windows Sockets API,但结果相同。
否则,您似乎在任何一种情况下都在进行轮询(避免阻塞等待),因此这两种方法都可以。只要您不让自己处于阻塞状态(例如,在没有数据时读取,在缓冲区已满时写入),就没有任何区别。
也许第一种方法更容易编码/理解;所以,就这样吧。
您可能会对查看 libev 的文档感兴趣和 c10k problem有关此主题的有趣想法/方法。
关于c++ - 异步事件循环设计和问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2779901/