Python全局变量线程安全吗?
编辑:我想问一下,在像tornado这样的单线程网络框架中,全局变量是否安全。
我正在使用mongoengine这个ORM,它通过一个全局变量来获取数据库连接:
_get_db() # gets the db connection
我还在使用tornado,这是一个单线程的Python网络框架。在某个特定的视图中,我需要获取一个数据库连接,并解引用一个DBRef
对象(类似于外键):
# dereference a DBRef
_get_db().dereference(some_db_ref)
因为_get_db
返回的连接是一个全局变量,所以是否有可能出现冲突,导致错误的值被返回到错误的线程?
4 个回答
1
不,锁在Python中使用起来其实很简单。你可以使用try: finally: 这种模式,确保在你修改全局变量之后,锁能够被释放。
3
在与Python对象打交道时,线程总是需要持有全局解释器锁(GIL)。存放变量的命名空间也是一个Python对象(根据变量的类型,它可以是frameobject或dict)。在多个线程中获取或设置变量是完全安全的,你不会得到错误的数据。
不过,通常的竞争条件仍然适用,也就是说你获取到的对象或者在赋值时替换的对象可能会有问题。像 x += 1
这样的语句是 不安全 的,因为在获取和存储之间,另一个线程可能会运行,改变 x
的值,而你接下来又会覆盖这个值。
2
假设MongoEngine是基于PyMongo的(我相信是这样的),那么你就可以放心了。PyMongo是完全安全的,可以在多个线程中同时使用。