在Python中,从导入的模块线程初始化类变量是否安全



我知道类变量初始化发生在导入时。如果是这种情况,在下面的代码中,类A的类变量初始化是否会导致竞争条件?

a.py:

class A:
# Static code here...
pass

b.py:

class B:
def func(self):
from a import A

c.py:

import threading
from b import B
b1 = B()
b2 = B()
t1 = threading.Thread(target=b1.func)
t2 = threading.Thread(target=b2.func)
t1.start()
t2.start()
t1.join()
t2.join()

终端:

$ python c.py

在importlib的Cpython实现中,C端有一个线程锁,但为了确保安全,我运行了以下脚本:

导入的文件:

import time
print('importing, in imported file')
time.sleep(2) # drop the GIL
print('finished importing, in imported file')

导入文件:

import threading
def import_other_file():
print('going to import')
import ex12
print('finished importing')
t1 = threading.Thread(target=import_other_file)
t2 = threading.Thread(target=import_other_file)
t1.start()
t2.start()
t1.join()
t2.join()

输出:

going to import
going to import
importing, in imported file
finished importing, in imported file
finished importing
finished importing

类A的类变量初始化是否会导致竞争条件?

所以,由于C侧锁定,将不会出现竞争条件。

我相信由于全局解释器锁定,这里没有数据竞争(假设您使用的是CPython或类似的实现(。在任何给定时间,只有一个线程可以执行Python字节码。

然而,不能(或者至少不应该(依赖两个线程中的哪个最终实际首先导入A

最新更新