我似乎明白了:
POSIX AIO
API是原型<aio.h>
并且您将程序与librt(-lrt)链接,而libaio
API <libaio.h>
和您的程序中的API 与libaio(-laio)链接.
我无法弄清楚:
1.内核是否以不同的方式处理这两种方法中的任何一种?
2. O_DIRECT
使用其中任何一个标志是强制性的吗?
正如在这篇文章中提到的,libaio 在没有O_DIRECT
使用的情况下工作正常libaio
.但是,理解但是:
根据R.Love的Linux系统编程书,Linux只支持常规文件上的aio(我假设它是POSIX AIO).只有在打开O_DIRECT
的小程序(使用aio.h,与-lrt链接)调用aio_write
时没有O_DIRECT
标志打开的文件没有问题.
考虑一个受CPU限制的应用程序,但也具有高性能I/O要求.
我正在将Linux文件I/O与Windows进行比较,我看不出epoll将如何帮助Linux程序.内核会告诉我文件描述符"准备好读取",但是我仍然需要调用阻塞read()来获取我的数据,如果我想读取兆字节,那么很明显它会阻塞.
在Windows上,我可以创建一个设置了OVERLAPPED的文件句柄,然后使用非阻塞I/O,并在I/O完成时收到通知,并使用该完成函数中的数据.我需要不花费应用程序级别的挂钟时间等待数据,这意味着我可以精确地将我的线程数调整为我的内核数量,并获得100%的高效CPU利用率.
如果我必须在Linux上模拟异步I/O,那么我必须分配一些线程来执行此操作,并且这些线程将花费一些时间来处理CPU事务,并且大量时间阻塞I/O,此外,在这些线程的消息传递中会有开销.因此,我将过度订阅或利用我的CPU核心.
我把mmap()+ madvise()(WILLNEED)视为"穷人的异步I/O",但它仍然没有完全通过那里,因为当它完成时我无法得到通知 - 我有"猜测",如果我猜"错误",我将最终阻止内存访问,等待数据来自磁盘.
Linux似乎在io_submit中启动了异步I/O,它似乎也有一个用户空间POSIX aio实现,但它已经有一段时间了,我知道没有人会担保这些系统的关键,高性能的应用程序.
Windows模型的工作方式大致如下:
步骤1/2通常作为单个事物完成.步骤3/4通常使用工作线程池完成,而不是(必要)与发出I/O相同的线程.这个模型有点类似于boost :: asio提供的模型,除了boost :: asio实际上不会给你异步的基于块的(磁盘)I/O.
Linux中epoll的不同之处在于,在步骤4中,还没有I/O发生 - 它会在步骤4之后提升第1步,如果你确切知道你需要的话,那就是"向后".
编写了大量的嵌入式,桌面和服务器操作系统之后,我可以说这种异步I/O模型对于某些类型的程序来说非常自然.它还具有非常高的吞吐量和低开销.我认为这是Linux I/O模型在API级别上仍然存在的真正缺点之一.
有没有办法以读取或写入的方式在远程文件系统(如NFS,SSHFS或sambafs)上写入和读取文件,甚至可以立即打开并返回错误代码?事实上我正在使用Twisted,我想知道是否有一种安全的方法来访问远程文件而不会阻塞我的反应堆.
我正在研究一种TFTP实现,它正在从一个复杂的多线程实现过渡到单线程/单进程实现,它使用状态机来跟踪连接的会话状态.TFTP很简单,并发会话的数量足够小,除了大量的代码大小和复杂性节省之外,确实对软件没有任何影响.
当然,当其他人连接时,我不能阻止单个会话.为了解决这个问题,我的第一个想法是POSIX AIO,虽然经过一些研究我读到了它
此链接中包含一个示例(http://davmac.org/davpage/linux/async-io.html),但我也发现了其他链接.从'08开始,先前的stackoverflow帖子(POSIX异步I/O(AIO)的状态是什么?)给出了一些额外的观点.
对于C开发人员来说,AIO仍然像人们声称的那样破碎吗?人们真的不使用AIO,主要坚持轮询/选择或有限大小的线程池吗?
我正在尝试在 Mac OS X 下将 aio_* 函数用于异步文件 IO,但是我在将某种形式的用户数据获取到信号处理程序中时遇到了问题。
这是设置操作的代码:
class aio_context {
public:
aio_context(int fildes, boost::uint64_t offset,
const MyBufferClassPtr &buffer)
{
// The aiocb struct must be zeroed
memset(&m_aiocb, 0, sizeof(struct aiocb));
// Set what to do
m_aiocb.aio_fildes = fildes;
m_aiocb.aio_buf = buffer->data();
m_aiocb.aio_nbytes = buffer->size();
m_aiocb.aio_offset = offset;
// Set notification
m_aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
m_aiocb.aio_sigevent.sigev_signo = SIGUSR1;
// ATTEMPT TO SET A VALUE THAT CAN BE READ IN THE HANDLER
m_aiocb.aio_sigevent.sigev_value.sival_ptr = this;
}
struct aiocb* GetAiocbp()
{
return …
Run Code Online (Sandbox Code Playgroud) aio ×3
posix ×3
asynchronous ×2
linux ×2
c ×1
c++ ×1
filesystems ×1
io ×1
linux-kernel ×1
macos ×1
networking ×1
python ×1
signals ×1
sockets ×1
twisted ×1