python多线程读取只读内存缓冲区绕过GIL

时间:2016-11-01 04:34:24

标签: python multithreading gil ramdisk

我在磁盘上有很多文件需要读取,第一个选项是使用多线程,它在SSD上表现很好。 (当线程被IO阻塞时,它将释放GIL)

但我希望在没有SSD的情况下实现类似或更快的速度,因此我将它们预先加载到内存中(如存储在dict中),并且每个线程都将从内存中读取每个文件内容。不幸的是,也许是因为GIL,dict中存在锁定,因此其速度甚至比从SSD加载文件还要慢!

所以我的问题是,有没有任何解决方案可以创建一个没有锁/ GIL的只读内存缓冲区?像ramdisk或其他什么>

2 个答案:

答案 0 :(得分:1)

简而言之,没有。

尽管Python(特别是CPython)是一种多线程语言,但在任何时刻解释器都只能运行一段python代码。因此,如果你的纯python程序不包含阻塞I / O(例如访问无锁内存缓冲区),无论你做什么,它都会降低单线程程序的性能。从表面来看,性能将比实际的单线程程序更糟糕,因为与其他线程同步会产生开销。

(特别感谢Graham Dumpleton!)其中一个solution是为CPython编写C扩展。并在进入“C境界”时释放GIL。请注意,如果没有GIL保护,您将无法访问python内容,否则会导致细微错误或直接崩溃。

有几种实现不使用GIL,例如,Jython和Cython(非CPython)。你可以尝试使用它们。但请记住,编写正确的多线程程序很难。编写快速多线程程序更加困难。我的建议是编写多进程程序而不是多线程。并通过IPC等传递数据(比方说,ZeroMQ,它易于使用且轻量级)。

答案 1 :(得分:0)

让我在@HKTonyLee回答中添加几点。

所以Python有这个GIL。但是在执行文件I / O时会释放它。这意味着您可以并行读取文件。从进程的角度来看,没有文件这样的东西,只有文件描述符(假设是posix),然后无论你读什么它都不必存储在磁盘上。

总而言之,如果您将文件移动到(例如)tmpfs或ramdisk或任何等效文件,那么您应该使用SSD获得更好的性能。但请注意风险:如果您需要修改文件,可能会丢失更新。