Python、ctypes和mmap

13 投票
2 回答
4668 浏览
提问于 2025-04-16 03:41

我在想,ctypes这个包能不能和mmap一起使用。

目前,我的模块是先用create_string_buffer分配一个缓冲区,然后通过byref把这个缓冲区传给我的库中的mylib.read函数。顾名思义,这个函数是用来把数据读入缓冲区的。接着,我调用file.write(buf.raw)把数据写入磁盘。不过,我的测试结果显示,这样做效率并不高(在file.write上花的时间,其实应该花在mylib.read上)。

所以,我想知道ctypes能不能和mmap一起使用。如果我有一个mmap.mmap实例和一个偏移量,我该怎么才能获取到一个指针(c_void_p)指向那个地址空间呢?

2 个回答

1

要知道,操作系统在使用read()的时候会自动进行预读。这意味着你在执行read()或write()时会有一个操作被阻塞,也就是说其中一个会变得比较慢,但即使你在一个操作上被阻塞,另一个操作仍然会在后台进行。这就是多任务操作系统的工作原理。

如果你使用mmap来处理这个问题,很可能会让操作系统的工作变得更复杂。这样一来,操作系统就更难判断你其实只是想简单地读写数据,也会让它在进行预读时变得更加困难。虽然操作系统可能还是能搞明白(它们在这方面非常厉害),但你可能并没有在帮忙。

原则上,使用mmap的唯一好处是可以避免内存复制的开销,但听起来这并不是你想要的目标(而且除非有明确的性能分析结果,否则我很怀疑这会对性能有帮助)。

14

一个 mmap 对象“支持可写的缓冲区接口”,所以你可以使用 from_buffer 这个类方法。所有的 ctypes 类都有这个方法,你可以把 mmap 实例作为参数传进去,这样就能创建一个你想要的 ctypes 对象,也就是说,它可以共享 mmap 实例所映射的内存(也就是底层的文件)。我想具体来说,你可能会想要一个合适的 ctypes 数组

撰写回答