我该如何将以下Java代码翻译为Python?
AtomicInteger cont = new AtomicInteger(0);
int value = cont.getAndIncrement();
我该如何将以下Java代码翻译为Python?
AtomicInteger cont = new AtomicInteger(0);
int value = cont.getAndIncrement();
在使用该值时,最好使用threading.Lock
进行保护。在Python中没有原子修改,除非你使用pypy(如果你使用,可以看一下stm版本中的__pypy__.thread.atomic
)。
with your_lock: variable += 1
可能更简洁。 - viraptorvariable
中取出value
。 - Michael Molitertools.count
返回一个迭代器,每次迭代时相当于执行 getAndIncrement()
。import itertools
cont = itertools.count()
value = next(cont)
这将执行相同的功能,尽管其不是像“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
__getattr__
,__getattribute__
可能在子类中被实现)。(另外,我添加了int(x)来保护输入不是不可变的、线程安全对象的情况)。 - user48956使用atomics
库,相同的代码可以用Python编写:
import atomics
a = atomics.atomic(width=4, atype=atomics.INT)
value = a.fetch_inc()
这种方法严格保证无锁。
注意:我是该库的作者。
width=4
是什么?通过阅读文档,我并不清楚。此外,为什么我要关心宽度呢?文档还应该包括一个GitHub链接以供贡献,并提供像这个答案中新手可以理解的简单示例,而不是直接跳到像测试多个线程的正确性或内存映射访问之类的复杂内容。 - Victor Stafusa - BozoNaCadeia已经 8 年了,仍然没有不使用任何外部库的 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)
Python原子操作用于共享数据类型。
该模块可用于多进程和多线程条件下的原子操作。高性能Python!高并发,高性能!
使用多进程和多线程的原子API示例:
您需要以下步骤来利用该模块:
创建函数,供子进程使用,参考UIntAPIs、IntAPIs、BytearrayAPIs、StringAPIs、SetAPIs、ListAPIs,在每个进程中,您可以创建多个线程。
def process_run(a):
def subthread_run(a):
a.array_sub_and_fetch(b'\0x0F')
threadlist = []
for t in range(5000):
threadlist.append(Thread(target=subthread_run, args=(a,)))
for t in range(5000):
threadlist[t].start()
for t in range(5000):
threadlist[t].join()
创建共享的bytearray
a = atomic_bytearray(b'ab', length=7, paddingdirection='r', paddingbytes=b'012', mode='m')
启动进程/线程以利用共享的bytearray
processlist = []
for p in range(2):
processlist.append(Process(target=process_run, args=(a,)))
for p in range(2):
processlist[p].start()
for p in range(2):
processlist[p].join()
assert a.value == int.to_bytes(27411031864108609, length=8, byteorder='big')