以下代码是否是线程安全的?
只有一个/第一个线程设置变量set_this_var_only_once吗?
set_this_var_only_once = None
def worker():
global set_this_var_only_once
if set_this_var_only_once is None:
set_this_var_only_once = "not None"
for i in range(10):
t = threading.Thread( target=worker )
t.daemon=True
t.start()
答案 0 :(得分:4)
你需要像这样锁定变量:
from threading import Lock
lock = Lock()
set_this_var_only_once = None
def worker():
with lock:
if set_this_var_only_once is None:
set_this_var_only_once = "not None
答案 1 :(得分:3)
绝对不是。
在执行下一行之前,两个线程很可能执行此行:
if set_this_var_only_once is None:
之后,两个线程都将执行下一行:
set_this_var_only_once = "not None"
您可以使用locks来阻止:
lock = threading.Lock()
def worker():
lock.acquire()
if set_this_var_only_once is None:
set_this_var_only_once = "not None"
lock.release()
只有一个线程能够获取锁。如果另一个线程在锁定时尝试获取它,则对lock.acquire()
的调用将阻塞并等待第一个线程锁定释放。然后锁定将由另一个线程获取。
这样可以确保lock.acquire()
和lock.release()
之间的代码一次只能在一个线程中执行。
修改强>
正如Gerhard在the other answer中指出的那样,你可以使用带有锁的context management protocol:
with lock:
if set_this_var_only_once is None:
set_this_var_only_once = "not None"
这也将确保在锁定块内发生异常时正确释放锁。
答案 2 :(得分:1)
不,不是。
如果另一个线程在获取当前线程后获得控制权 变量,它可以获取变量,递增变量并写入变量 回来,在当前线程做同样的事情之前。因为他们是 两者都看到相同的原始值,只会计算一个项目 对
Here's这篇关于它的好文章。
P.S。 worker()中还需要以下行:
global set_this_var_only_once