Oli*_*ver 17 python queue multithreading scope
我有一个脚本创建一堆线程,运行程序使用线程从队列中运行任务,并从每个线程返回一些东西.我想计算其中有多少成功返回,所以我设置一个变量"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
Run Code Online (Sandbox Code Playgroud)
unu*_*tbu 20
successful+=1
Run Code Online (Sandbox Code Playgroud)
不是一个线程安全的操作.当多个线程试图递增共享的全局变量时,可能会发生冲突并且successful不会正确递增.
要避免此错误,请使用锁定:
lock = threading.Lock()
def foo():
global successful
while True:
...
with lock:
successful+=1
Run Code Online (Sandbox Code Playgroud)
下面是一些代码来证明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)
Run Code Online (Sandbox Code Playgroud)
收益率:
% test.py
1539065
% test.py
1436487
Run Code Online (Sandbox Code Playgroud)
这些结果不一致,并且小于预期的2000000.取消注释锁定会产生正确的结果.
出现此问题是因为在函数内分配的变量被视为该函数的本地变量.如果要修改在a successfull之外创建的变量的值,则foo需要明确告知解释器您将在函数内使用全局变量.这可以通过以下方式完成:
def foo():
global successfull
while True:
task=q.get()
#do some work
print task
successful+=1 # triggers an error
q.task_done()
Run Code Online (Sandbox Code Playgroud)
现在代码应该按预期工作.
| 归档时间: |
|
| 查看次数: |
19672 次 |
| 最近记录: |