Python,反原子增量

use*_*041 35 python

如何将以下代码从Java转换为Python?

AtomicInteger cont = new AtomicInteger(0);

int value = cont.getAndIncrement();
Run Code Online (Sandbox Code Playgroud)

vir*_*tor 31

最有可能threading.Lock使用该值.除非你使用pypy,否则Python中没有原子修改(如果你这样做,请查看__pypy__.thread.atomicstm版本).

  • `with your_lock:variable + = 1`可能更短. (15认同)
  • @viraptor,不要忘记在锁仍然保持时从`variable` 中获取`value` (3认同)
  • 我使用锁的acquire()和release()来工作,但是我认为这不像Java中的原子类那样有效。 (2认同)

Wil*_*ley 22

itertools.count返回一个迭代器,它将getAndIncrement()在每次迭代时执行等效操作.

例:

import itertools
cont = itertools.count()
value = cont.next()
Run Code Online (Sandbox Code Playgroud)

  • [是](https://github.com/akheron/cpython/blob/d04cd9a21a22a56ec3cb577229808c019217b8e0/Modules/itertoolsmodule.c#L3999) (19认同)
  • 暂时忽略了我在使用依赖于GIL进行同步的定时炸弹的犹豫,是什么让你说这绝对是一次操作?它是单个_function call_,但它是单字节码操作吗? (18认同)
  • @WillManley它依赖于CPython(和PyPy)的实现细节,依靠实现细节并不是一个好习惯.此外,它在Jython上不安全,请参阅:http://www.jython.org/jythonbook/en/1.0/Concurrency.html#no-global-interpreter-lock和:https://bitbucket.org/jython/ jython/src/91083509a11cdeadc9407b4d9a1ece2b8ffc45ce/src/org/python/modules/itertools/count.java?at = default&fileviewer = file-view-default#count.java-109请更新帖子. (13认同)
  • @JianggeZhang我仍然同意科林的犹豫.在许多情况下,依赖_contingency_进行同步是不明智的:即,实现超出"合同"和方法意图的_currently_实现方式的隐含细节.这无异于依赖副作用.对于某些情况,这可能没什么问题,但是一般情况下它仍然是不确定的 (10认同)
  • 乍一看这似乎不是线程安全的,是吗? (9认同)
  • GIL保证它是因为`cont.next()`是一个增加并返回值的单个操作.因此它在CPython和PyPy上是安全的.我不知道Jython. (2认同)
  • @WillManley你在哪里看到它是一个原子操作,那里有多个操作 - 我错过了什么? (2认同)
  • 它是 C 语言中的多个操作,但它是一个用于保存 GIL 的 Python 字节码操作。 (2认同)

doo*_*pav 18

使用该atomics库,可以用 Python 编写相同的内容,如下所示:

import atomics


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

value = a.fetch_inc()
Run Code Online (Sandbox Code Playgroud)

该方法是严格无锁的。

注意:我是这个库的作者

  • 不用担心,只是想让你知道。顺便说一句,干得好。 (2认同)

use*_*956 5

这将执行相同的功能,尽管它不是无锁的,并且暗示“ AtomicInteger”。

请注意,其他方法也不是严格无锁的,它们依赖于GIL并且在python解释器之间不可移植。

class AtomicInteger():
    def __init__(self, value=0):
        self._value = value
        self._lock = threading.Lock()

    def inc(self):
        with self._lock:
            self._value += 1
            return self._value

    def dec(self):
        with self._lock:
            self._value -= 1
            return self._value


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

    @value.setter
    def value(self, v):
        with self._lock:
            self._value = v
            return self._value
Run Code Online (Sandbox Code Playgroud)