如果/我应该使用线程更新全局变量怎么办.[pythonic方式] [英] What if/ should I use threading to update global variables.[pythonic way]
问题描述
我有一个更新全局/类变量的函数.那么,定期调用子线程等函数后应该注意什么?(异步方式)
I have a function to update a global/class variable. So, What should care after regularly invoke such function as subthread?(in asynchronous way)
或者,有什么建议可以避免使用这种模式?(病态的方式)
Or, any suggestions to avoid using this pattern? (the pathonic way)
import time
import threading
# through global variable or class variable
_a = 123
def update_a(): # may be called more than once
"slow updating process"
time.sleep(3)
global _a
_a += 10
return
if __name__ == '__main__':
print(_a)
th = threading.Thread(target=update_a)
th.setDaemon(True)
th.start()
print(_a)
# updating aynchrounously
time.sleep(5)
print(_a)
推荐答案
这表明 添加不是线程安全的(请参阅 Josiah Carlson 的评论.effbot.org
现在似乎已关闭;您可以查看存档版本通过 这里的回程机.):
This demonstrates that addition is not threadsafe (See Josiah Carlson' comment. effbot.org
seems to be down right now; you can check out an archived version of the page through the wayback machine here.):
import threading
x = 0
def foo():
global x
for i in xrange(1000000):
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)
产生一些小于 2000000 的数字.这表明对 x += 1
的一些调用没有正确更新变量.
yields some number less than 2000000. This shows that some calls to x += 1
did not properly update the variable.
解决方案是使用锁保护对全局变量的赋值:
The solution is to protect assignment to your global variable with a lock:
lock = threading.Lock()
def safe_foo():
global x
for i in xrange(1000000):
with lock:
x += 1
x = 0
threads = [threading.Thread(target=safe_foo), threading.Thread(target=safe_foo)]
for t in threads:
t.daemon = True
t.start()
for t in threads:
t.join()
print(x)
产量为 2000000.
yields 2000000.
这篇关于如果/我应该使用线程更新全局变量怎么办.[pythonic方式]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!