Python cStringIO 线程安全吗?
如标题所说,Python的cStringIO在多线程使用时是否保护它们的内部结构?
谢谢。
4 个回答
这个操作在“线程安全”方面的表现就像文件操作一样(也就是说——并不是很好)。你正在使用的Python版本有一个叫做全局解释器锁(GIL)的东西,它可以确保每次对cStringIO
的文件操作不会被其他线程打断。不过,这并不意味着多个线程同时进行的文件操作不会交错在一起。
我猜你是在说Python的CPython实现。
在CPython中,有一个叫做全局解释器锁的东西,这意味着同一时间只能有一个Python代码线程在运行。所以,如果你用C语言写的代码,也会基本上是单线程的,除非它特别释放了这个全局锁。
这就意味着,如果你有多个Python线程同时使用cStringIO,那是没问题的,因为在任何时候只能有一个cStringIO的方法在运行,而且cStringIO从来不会释放这个锁。不过,如果你从C代码直接调用它,而这个C代码是在锁外运行的,那就会出问题。此外,如果你做的事情比简单的读写更复杂,比如使用seek
,那么你的调用可能会以意想不到的方式重叠,从而导致问题。
还要注意,有些方法像writelines
可能会在方法内部调用Python代码,所以在这种情况下,你可能会在一次writelines
的调用中看到其他输出交错在一起。
这对于大多数标准Python对象都是成立的:你可以安全地在多个线程中使用这些对象,因为单个操作不会出错,但事情发生的顺序就不一定了。
看看这篇很棒的文章,里面详细解释了GIL(全局解释器锁)。另外要注意,cStringIO这个模块是纯用C语言写的,它的调用不会释放GIL。
这意味着在执行read()或write()的时候,正在运行的线程不会主动切换到其他线程(这是基于当前虚拟机的实现)。虽然操作系统可以强制中断这个线程,但其他Python线程还是无法获得GIL。
如果想了解更多,可以看看源代码:Python-2.7.1/Modules/cStringIO.c,里面没有提到内部保护的内容。如果有疑问,查看源代码总是个好主意 :)