linux aio api包装器
libaio的Python项目详细描述
Linux AIO API包装器
这是关于内核的,基于文件描述符的异步I/O。 它与asyncio标准模块无关。
Linux AIO primer
当发送或期望数据时,开发人员面临的典型问题是 当操作完成时,程序才能继续。
- read/write/recv/send:blocks直到事情发生
- 同样,在非阻塞文件描述符上:错误输出而不是阻塞, developper必须以某种方式实现retry,并且可能会浪费cpu时间 只是一遍又一遍地重新提交同一个操作。
- select/poll/epoll:kernel告诉程序何时(重新)提交操作 不应该阻塞(如果开发人员小心没有竞争的IO源)
aio是下一个级别:应用程序表示一些io 当文件描述符接受它并提供 与内核对应的缓冲区。 与select/poll/epoll相比,这避免了当 操作成为可能:
- 内核发送通知(例如:fd是可读的)
- 程序启动实际IO(例如:从FD读取)
相反,内核只需通知userland操作已经完成, 应用程序可以处理接收到的数据,或者提交更多的数据来发送。
Edge cases
因为这种高层次的集成,低层次的实现 由高开销api抽象的约束可能会变得明显。
例如,当将aio块提交到usb gadget端点文件时, 块应与页边界对齐,因为某些USB设备控制器 无法读取/写入部分页面。
在python中,这意味着应该使用mmap来分配这样的缓冲区 任何bytearray的。
实现细节出现的另一个地方是完成状态, res和res2。它们的含义取决于模块处理操作 在使用的文件描述符上,因此python libaio在没有 假设它们的意义(而不是,比方说,提高负面价值)。
另一个地方是应用程序启动的闭包:有一个基本的 取消aio块时的竞争条件(可能是硬件触发的 完成将首先发生,或者软件启动的取消将)。 在任何情况下,都会产生一个完成事件,应用程序可以检查 哪个来源赢了。其结果是,aio上下文关闭可能 时间:请求取消时不阻止,软件应等待 将缓冲区退回的硬件。
python 2 Notes
在Python2.7中,一个bytearray的内存视图尽管是可写的,但是被拒绝了 按类型:
>>>fromctypesimportc_char>>>a=bytearray(b'foo')>>>c_char.from_buffer(a)c_char('f')>>>b=memoryview(a)>>>b.readonlyFalse>>>c_char.from_buffer(b)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:expectedawriteablebufferobject
这意味着在 不需要复制内存的大缓冲区的开始。
同样的代码在Python3.x中也可以正常工作。
这被认为是Python2.7cTypes或MemoryView错误,而不是PythonLibaio错误。
此外,memoryView拒绝使用mmap对象:
>>>importmmap>>>a=mmap.mmap(-1,16*1024)>>>b=memoryview(a)Traceback(mostrecentcalllast):File"<stdin>",line1,in<module>TypeError:cannotmakememoryviewbecauseobjectdoesnothavethebufferinterface>>>
…但cTypes对此很满意:
>>>importctypes>>>c=(ctypes.c_char*len(a)).from_buffer(a)>>>
…并且memoryView接受在ctype对象上构造:
>>>d=memoryview(c)>>>
…而且真的很管用!
>>>a[0]'\x00'>>>c[0]'\x00'>>>d[0]'\x00'>>>d[0]='\x01'>>>c[0]'\x01'>>>a[0]'\x01'>>>a[0]='\x02'>>>c[0]'\x02'>>>d[0]'\x02'
这被认为是Python2.7MemoryView或MMAP错误。