Python、ctypes和mmap
我在想,ctypes这个包能不能和mmap一起使用。
目前,我的模块是先用create_string_buffer
分配一个缓冲区,然后通过byref
把这个缓冲区传给我的库中的mylib.read
函数。顾名思义,这个函数是用来把数据读入缓冲区的。接着,我调用file.write(buf.raw)
把数据写入磁盘。不过,我的测试结果显示,这样做效率并不高(在file.write
上花的时间,其实应该花在mylib.read
上)。
所以,我想知道ctypes能不能和mmap一起使用。如果我有一个mmap.mmap
实例和一个偏移量,我该怎么才能获取到一个指针(c_void_p
)指向那个地址空间呢?
2 个回答
要知道,操作系统在使用read()的时候会自动进行预读。这意味着你在执行read()或write()时会有一个操作被阻塞,也就是说其中一个会变得比较慢,但即使你在一个操作上被阻塞,另一个操作仍然会在后台进行。这就是多任务操作系统的工作原理。
如果你使用mmap来处理这个问题,很可能会让操作系统的工作变得更复杂。这样一来,操作系统就更难判断你其实只是想简单地读写数据,也会让它在进行预读时变得更加困难。虽然操作系统可能还是能搞明白(它们在这方面非常厉害),但你可能并没有在帮忙。
原则上,使用mmap的唯一好处是可以避免内存复制的开销,但听起来这并不是你想要的目标(而且除非有明确的性能分析结果,否则我很怀疑这会对性能有帮助)。
一个 mmap
对象“支持可写的缓冲区接口”,所以你可以使用 from_buffer 这个类方法。所有的 ctypes
类都有这个方法,你可以把 mmap
实例作为参数传进去,这样就能创建一个你想要的 ctypes
对象,也就是说,它可以共享 mmap
实例所映射的内存(也就是底层的文件)。我想具体来说,你可能会想要一个合适的 ctypes
数组。