Cython/Pyrex生成的Python扩展线程安全吗?

4 投票
2 回答
1887 浏览
提问于 2025-04-15 14:10

如果不是的话,有没有什么方法可以通过特定的编程方式来确保线程安全呢?

为了更清楚,我说的“线程安全”是指Python中的线程,而不是操作系统层面的线程。

2 个回答

2

Python的全局解释器锁(GIL)意味着在任何时候,解释器里只能有一个线程在活动。不过,一旦控制权交给了C语言的扩展,其他线程就可以在解释器里活动。虽然可以创建多个线程,但这并不意味着一个线程在执行关键代码时不会被打断。

在解释器内部,不能保证代码是线程安全的,也就是说,解释器里运行的代码本身并不一定是安全的。即使是C或Pyrex模块中的代码,也可以修改那些Python代码能看到的数据结构。当然,原生代码也可能会遇到与原生数据结构相关的线程问题。

想要保证线程安全,必须使用合适的设计和同步方法——Python解释器中的GIL并不会实质性地改变这一点。

5

这完全取决于你的Cython代码和Python的全局解释器锁(GIL)之间的互动,详细信息可以在这里找到。如果你没有做特别的处理,Cython生成的代码会遵循GIL的规则(同样,C语言编写的扩展如果不使用释放GIL的宏,也会遵循这个规则);这使得这样的代码“和Python代码一样线程安全”——虽然这并不算太安全,但比完全不受限制的多线程代码要好处理得多(你仍然需要设计多线程之间的合作和同步,最好使用队列实例,但也可能需要使用锁等手段)。

已经释放了GIL但还没有重新获取的代码,绝对不能以任何方式与Python运行时及其使用的对象进行互动——这对Cython同样适用,也适用于C语言编写的扩展。当然,这样做的好处是,这段代码可以在一个独立的核心上运行(当然,直到它需要再次与Python运行时同步或以其他方式进行通信)。

撰写回答