python线程可以访问命名空间中的变量吗? [英] Can python threads access variables in the namespace?
问题描述
我有一个脚本,该脚本创建一堆线程,运行一个程序以使用这些线程从队列中运行任务,并从每个线程返回一些信息.我想计算其中有多少成功返回,因此我设置了一个变量"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屋!