python - python线程可以访问命名空间中的变量吗?

标签 python multithreading scope queue

我有一个脚本可以创建一堆线程,运行一个程序来使用线程来运行队列中的任务,然后从每个线程返回一些东西。我想计算其中有多少成功返回,所以我设置了一个变量“successful=0”,并在每次队列报告任务成功完成时递增它。

但是,我收到“UnboundLocalError:在赋值前引用了局部变量‘成功’”

这是怎么回事?

下面是一些示例代码:

successful = 0

q = Queue(200)
for i in range(100):
    t=Thread(target=foo)
    t.daemon=True
    t.start()
def foo():
    while True:
        task=q.get()
        #do some work
        print task
        successful+=1 # triggers an error
        q.task_done()
for i in range(100):
    q.put("Foo")
q.join()
print successful

最佳答案

successful+=1

不是线程安全操作。多个线程尝试递增共享全局变量时,可能会发生冲突,成功 将无法正确递增。

为避免此错误,请使用锁:

lock = threading.Lock()
def foo():
    global successful
    while True:
        ...
        with lock:
            successful+=1 

下面是一些代码来证明 x += 1 不是线程安全的:

import threading
lock = threading.Lock()
x = 0
def foo():
   global x
   for i in xrange(1000000):
       # with lock:    # Uncomment this to get the right answer
            x += 1
threads = [threading.Thread(target=foo), threading.Thread(target=foo)]
for t in threads:
    t.daemon = True    
    t.start()
for t in threads:
    t.join()

print(x)

产量:

% test.py 
1539065
% test.py 
1436487

这些结果不一致,小于预期的 2000000。取消对锁的注释会产生正确的结果。

关于python - python线程可以访问命名空间中的变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11786530/

相关文章:

c - 验证解析器中的数据类型/结构

python - 计算经过的秒数

python - 访问小部件实例的 "height"属性

java - 在 Java 中是否有并行调用多个函数的简写方式?

asp.net - 如何有选择地在后台线程上运行一些代码?

javascript - 简单地访问其他命名空间的成员

python - 在 Python 中将类的实例追加到列表中会产生副本而不是引用

python - 在 Atom 中安装 Jupyter Notebook 错误 : Installing “jupyter-notebook@0.0.10” failed

android - 在 asynctask 中使用 asynctask

Javascript 方法和函数