
除非您想编写自己的IO线程池,否则glibc实现是可以接受的解决方案。实际上,对于完全在用户区中运行的某些东西,它实际上出奇地好。
根据我的经验,内核实现根本无法与缓冲IO一起使用(尽管我已经看到其他人说的相反!)。如果您想通过DMA读取大量数据,那很好,但是如果您打算利用缓冲区高速缓存,那当然会浪费很多时间。
另请注意,内核AIO调用实际上可能会阻塞。由于命令缓冲区的大小有限,因此较大的读取将分成几个较小的读取。队列填满后,异步命令将同步运行。惊喜
我在一两年前遇到了这个问题,找不到解释。问周围的问题给了我“是的,这就是它的工作原理”的答案。
据我了解,尽管有几种可行的解决方案似乎已经问世多年,但支持缓冲aio的“官方”兴趣也不是很大。我已经读过的一些论据是“无论如何都不想使用缓冲区”,“没人需要”和“大多数人甚至还没有使用epoll”。所以,嗯。
epoll直到最近,能够通过完成的异步 *** 作发出信号是另一个问题,但是与此同时,通过确实可以很好地工作
eventfd。
请注意,glibc实现实际上将按需 生成 线程
__aio_enqueue_request。这可能是没什么大不了的,因为产卵线程是不是 说
贵的要命了,而是应该意识到这一点。如果您对启动异步 *** 作的理解是“立即返回”,则该假设可能不正确,因为它可能首先产生了一些线程。
编辑 :
作为附带说明,在Windows下,存在与glibc AIO实现中的情况非常相似的情况,其中排队异步 *** 作的“立即返回”假设不成立。
如果您要读取的所有数据都在缓冲区高速缓存中,则Windows将决定改为 同步 运行请求 __,因为无论如何它都会立即完成。
这是有据可查的,而且听起来也很棒。除非要复制几兆字节,或者另一个线程发生页面错误或同时(同时争夺锁)IO(很可能是很长的时间),我看到的“立即”时间是2
-5毫秒。在大多数情况下这没有问题,但是例如在16.66ms帧时间的约束下,您可能不想冒随机时间阻塞5ms的风险。因此,“可以从我的渲染线程进行异步IO没问题,因为异步不会阻塞”这一天真假设是有缺陷的。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)