Python:多线程设置变量

时间:2016-10-18 05:26:06

标签: python multithreading python-2.7

以下代码是否是线程安全的?
只有一个/第一个线程设置变量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()

3 个答案:

答案 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