Python,计数器原子递增
我该如何把下面的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版本中的用法)。