Python,计数器原子递增

65 投票
5 回答
80650 浏览
提问于 2025-04-18 05:52

我该如何把下面的Java代码转换成Python代码呢?

AtomicInteger cont = new AtomicInteger(0);

int value = cont.getAndIncrement();

5 个回答

3

八年过去了,还是没有一个完整的示例代码来展示如何使用 threading.Lock 这个选项,而且不依赖任何外部库……现在给大家带来了:

import threading

i = 0
lock = threading.Lock()

# Worker thread for increasing count
class CounterThread(threading.Thread):
    def __init__(self):
        super(CounterThread, self).__init__()
        
    def run(self):
        lock.acquire()
        global i
        i = i + 1
        lock.release()


threads = []
for a in range(0, 10000):
    th = CounterThread()
    th.start()
    threads.append(th)

for thread in threads:
    thread.join()

global i
print(i)
18

使用atomics这个库,下面的代码可以用Python写成:

import atomics


a = atomics.atomic(width=4, atype=atomics.INT)

value = a.fetch_inc()

这个方法是完全不需要锁的。

注意:我是这个库的作者。

22

这个做的事情和之前的一样,不过它并不是像名字“AtomicInteger”所暗示的那样没有锁。

另外,其他一些方法也并不完全没有锁——它们依赖于全局解释器锁(GIL),而且在不同的Python解释器之间不能通用。

class AtomicInteger():
    def __init__(self, value=0):
        self._value = int(value)
        self._lock = threading.Lock()
        
    def inc(self, d=1):
        with self._lock:
            self._value += int(d)
            return self._value

    def dec(self, d=1):
        return self.inc(-d)    

    @property
    def value(self):
        with self._lock:
            return self._value

    @value.setter
    def value(self, v):
        with self._lock:
            self._value = int(v)
            return self._value
33

itertools.count 是一个可以返回迭代器的工具,每次循环的时候,它会像 getAndIncrement() 这样自动增加数字。

举个例子:

import itertools
cont = itertools.count()
value = next(cont)
52

很可能是用一个 threading.Lock 来保护对这个值的使用。在Python中,除非你使用pypy,否则没有原子修改的概念(如果你使用pypy,可以看看 __pypy__.thread.atomic 在stm版本中的用法)。

撰写回答