如何在python中创建一个线程安全的全局计数器

时间:2021-04-08 21:01:29

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线程。如何锁定线程?

2 个解决方案

#1


9  

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

#2


3  

The simplest solution is to protect the counter with a multiprocessing.Lock. I like to keep it in a class, like so:

最简单的解决方案是使用多处理保护计数器。锁定。我喜欢将它保存在一个类中,如下所示:

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的博客。

#1


9  

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

#2


3  

The simplest solution is to protect the counter with a multiprocessing.Lock. I like to keep it in a class, like so:

最简单的解决方案是使用多处理保护计数器。锁定。我喜欢将它保存在一个类中,如下所示:

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的博客。