python线程可以访问命名空间中的变量吗? [英] Can python threads access variables in the namespace?

查看:99
本文介绍了python线程可以访问命名空间中的变量吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本,该脚本创建一堆线程,运行一个程序以使用这些线程从队列中运行任务,并从每个线程返回一些信息.我想计算其中有多少成功返回,因此我设置了一个变量"successful = 0",并在每次队列报告任务成功完成时将其递增.

I have a script that creates a bunch of threads, runs a program to use the threads to run tasks from a queue, and returns something from each thread. I want to count how many of these returned successfully, so I set a variable "successful=0" and increment it every time the queue reports a task completed successfully.

但是,我收到"UnboundLocalError:分配前已引用本地变量成功""

However, I'm getting "UnboundLocalError: local variable 'successful' referenced before assignment"

这是怎么回事?

下面是一些示例代码:

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

不是线程安全的操作.如果有多个线程试图增加一个共享的全局变量,则可能会发生冲突,并且successful不会正确地增加.

is not a thread-safe operation. With multiple threads trying to increment a shared global variable, collisions may happen and successful will not be incremented properly.

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

To avoid this error, use a lock:

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


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


Here is some code to demonstrate that x += 1 is not threadsafe:

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.取消对该锁的注释会产生正确的结果.

These results do not agree and are less than the expected 2000000. Uncommenting the lock yields the correct result.

这篇关于python线程可以访问命名空间中的变量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆