如何在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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 15:58:41  来源:igfitidea点击:

how to make a thread-safe global counter in python

pythonmultithreading

提问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.Queueassigned 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 的博客,这里