Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
linux上的缓冲异步文件I/O_Linux_Asynchronous_Io_Linux Kernel_Aio - Fatal编程技术网

linux上的缓冲异步文件I/O

linux上的缓冲异步文件I/O,linux,asynchronous,io,linux-kernel,aio,Linux,Asynchronous,Io,Linux Kernel,Aio,我正在寻找在linux上执行异步文件I/O的最有效方法 POSIX glibc实现使用userland中的线程 本机aio内核api仅适用于非缓冲操作,内核中存在用于添加对缓冲操作支持的补丁,但这些补丁已经超过3年了,似乎没有人关心如何将它们集成到主线中 我还发现了很多其他的想法、概念和补丁,它们都支持异步I/O,尽管其中大多数都出现在已经超过3年的文章中。这一切在今天的内核中真正可用的是什么?我读过关于servlet、acall、内核线程的东西,还有更多我现在都不记得的东西 在今天的内核中,进

我正在寻找在linux上执行异步文件I/O的最有效方法

POSIX glibc实现使用userland中的线程

本机aio内核api仅适用于非缓冲操作,内核中存在用于添加对缓冲操作支持的补丁,但这些补丁已经超过3年了,似乎没有人关心如何将它们集成到主线中

我还发现了很多其他的想法、概念和补丁,它们都支持异步I/O,尽管其中大多数都出现在已经超过3年的文章中。这一切在今天的内核中真正可用的是什么?我读过关于servlet、acall、内核线程的东西,还有更多我现在都不记得的东西


在今天的内核中,进行缓冲异步文件输入/输出的最有效方法是什么?

除非您想编写自己的IO线程池,否则glibc实现是一个可接受的解决方案。对于完全在userland中运行的东西,它实际上运行得出奇地好

在我的经验中,内核实现根本不适用于缓冲IO(尽管我看到其他人的说法正好相反!)。如果您想通过DMA读取大量数据,这很好,但如果您计划利用缓冲区缓存,这当然会占用大量时间。
还要注意,内核AIO调用实际上可能会阻塞。有一个大小有限的命令缓冲区,大的读取被分成几个较小的读取。队列已满后,异步命令将同步运行。惊喜我一两年前遇到过这个问题,找不到解释。四处打听,我得到了“是的,当然是这样”的回答。
据我所知,支持缓冲aio的“官方”兴趣也不是特别大,尽管多年来似乎有几种可行的解决方案。我读到的一些论据是关于“你无论如何都不想使用缓冲区”和“没有人需要它”以及“大多数人甚至还没有使用epoll”。所以,好吧。。。嗯

直到最近,能够获得一个完成的异步操作发出的
epoll
信号是另一个问题,但在此期间,通过
eventfd
,这一点非常有效

请注意,glibc实现实际上会在
\uuuu aio\u enqueue\u请求中按需生成线程。这可能没什么大不了的,因为生成线程不再那么昂贵了,但我们应该意识到这一点。如果您对启动异步操作的理解是“立即返回”,那么该假设可能不正确,因为它可能首先生成一些线程

编辑
作为旁注,在Windows下,存在与glibc AIO实现中非常相似的情况,即排队等待异步操作的“立即返回”假设不成立。
如果您想要读取的所有数据都在缓冲区缓存中,Windows将决定改为同步运行请求,因为它将立即完成。这是有据可查的,诚然听起来也很棒。除非有几兆字节要复制,或者另一个线程有页面错误,或者并发执行IO(从而竞争锁),“立即”可能是一个惊人的长时间——我已经看到“立即”时间为2-5毫秒。这在大多数情况下都没有问题,但例如,在16.66ms帧时间的限制下,您可能不想冒险在随机时间阻塞5ms。因此,天真的假设“可以从我的渲染线程执行异步IO没有问题,因为异步不会阻塞”是有缺陷的。

该材料似乎很旧——好吧,它很旧——因为它已经存在很长时间了,虽然决不是琐碎的,但已经被很好地理解了。理查德·史蒂文斯(W.Richard Stevens)的一本绝妙绝伦的书(读《圣经》)中发表了一个你可以提出的解决方案。这本书是一本罕见的宝藏,清晰、简洁、完整:每一页都有真实而直接的价值:

另外两卷也是Stevens写的,是他Unix网络编程系列的前两卷:

(与芬纳和鲁道夫一起)和

我无法想象没有这三本基本的书;当我找到一个没听说过他们的人时,我目瞪口呆

还有更多史蒂文的书,同样珍贵:


我不认为异步文件I/O的Linux内核实现真的有用,除非您也使用O_DIRECT,对不起

这里有关于当前世界状态的更多信息:。它在2012年由曾在谷歌工作的人更新。

(2021)如果你的Linux内核足够新(至少5.1,但更新的内核带来了改进),那么*。这适用于缓冲I/O和直接I/O

在内核配方2019视频“通过IO实现更快IO”中,
IO
author。正如@Marenz所指出的,除非您想使用用户空间,否则线程
io\u uring
是执行缓冲异步I/O的唯一方法,因为

此外,在文章“现代存储速度非常快”中,使用了Optane设备。它要求Glauber有一个userspacereadahead实现(没有这个实现,缓冲I/O显然是赢家),但改进是令人印象深刻的


*这个答案的上下文显然与存储有关(在提到所有buffered一词之后)。对于网络I/O,在以后的内核中,
io已经稳步改进,可以与
epoll()
之类的东西进行交换,如果继续下去,总有一天会在所有情况下都是相同或更好的。

@Damon——一个漂亮的答案,谢谢!当你说“官方”对支持缓冲aio的兴趣不是很高”时,这似乎是一个很好的有力说明,aio并没有添加太多内容,无论用户程序多么想做aio,内核基本上忽略了他,只是做了它想做的事