如何在python中创建一个线程安全的全局计数器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35088139/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to make a thread-safe global counter in python
提问by L.fole
I'm creating a threading.Timer(2,work)
run threads. Inside each work function, upon some condition the global counter must increment without conflict for access of counter variable among the spawned work threads.
我正在创建一个threading.Timer(2,work)
运行线程。在每个工作函数内部,在某些情况下,全局计数器必须在不发生冲突的情况下递增,以便在产生的工作线程之间访问计数器变量。
I've tried Queue.Queue
assigned counter as well as threading.Lock()
. Which is a best way to implement thread-safe global increment variable.
我试过Queue.Queue
分配计数器以及threading.Lock()
. 这是实现线程安全全局增量变量的最佳方法。
Previously someone asked question here: Python threading. How do I lock a thread?
以前有人在这里问过问题:Python 线程。如何锁定线程?
采纳答案by mommermi
Not sure if you have tried this specific syntax already, but for me this has always worked well:
不确定您是否已经尝试过这种特定的语法,但对我来说这一直很有效:
Define a global lock:
定义全局锁:
import threading
threadLock = threading.Lock()
and then you have to acquire and release the lock every time you increase your counter in your individual threads:
然后每次在单个线程中增加计数器时都必须获取和释放锁:
with threadLock:
global_counter += 1
回答by Michael Foukarakis
The simplest solution is to protect the counter with a multiprocessing.Lock
. I like to keep it in a class, like so:
最简单的解决方案是用multiprocessing.Lock
. 我喜欢把它放在一个班级里,就像这样:
from multiprocessing import Process, RawValue, Lock
import time
class Counter(object):
def __init__(self, value=0):
# RawValue because we don't need it to create a Lock:
self.val = RawValue('i', value)
self.lock = Lock()
def increment(self):
with self.lock:
self.val.value += 1
def value(self):
with self.lock:
return self.val.value
def inc(counter):
for i in range(1000):
counter.increment()
if __name__ == '__main__':
thread_safe_counter = Counter(0)
procs = [Process(target=inc, args=(thread_safe_counter,)) for i in range(100)]
for p in procs: p.start()
for p in procs: p.join()
print (thread_safe_counter.value())
The above snippet was first taken from Eli Bendersky's blog, here.
上面的片段首先取自 Eli Bendersky 的博客,这里。