Python, counter atomic increment

Question:

How can I translate the following code from Java to Python?

AtomicInteger cont = new AtomicInteger(0);

int value = cont.getAndIncrement();
Asked By: user2983041

||

Answers:

Most likely with an threading.Lock around any usage of that value. There’s no atomic modification in Python unless you use pypy (if you do, have a look at __pypy__.thread.atomic in stm version).

Answered By: viraptor

itertools.count returns an iterator which will perform the equivalent to getAndIncrement() on each iteration.

Example:

import itertools
cont = itertools.count()
value = next(cont)
Answered By: Will Manley

This will perform the same function, although its not lockless as the name ‘AtomicInteger’ would imply.

Note other methods are also not strictly lockless — they rely on the GIL and are not portable between python interpreters.

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
Answered By: user48956

Using the atomics library, the same could would be written in Python as:

import atomics


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

value = a.fetch_inc()

This method is strictly lock-free.

Note: I am the author of this library

Answered By: doodspav

Python atomic for shared data types.

https://sharedatomic.top

The module can be used for atomic operations under multiple processs and multiple threads conditions. High performance python! High concurrency, High performance!

atomic api Example with multiprocessing and multiple threads:

You need the following steps to utilize the module:

  1. create function used by child processes, refer to UIntAPIs, IntAPIs, BytearrayAPIs, StringAPIs, SetAPIs, ListAPIs, in each process, you can create multiple threads.

     def process_run(a):
       def subthread_run(a):
         a.array_sub_and_fetch(b'x0F')
    
       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()
    
  2. create the shared bytearray

    a = atomic_bytearray(b'ab', length=7, paddingdirection='r', paddingbytes=b'012', mode='m')
    
  3. start processes / threads to utilize the shared 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')
    
Answered By: Xiquan Ren

8 years and still no full example code for the threading.Lock option without using any external library… Here it comes:

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)
Answered By: Mikel B
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.