2

I need to use atomic CompareAndSet operation in my python program, but I didn't find reference about how to use it.

Does python provide such atomic function?

Thank you.

leeshell
  • 31
  • 3
  • CPython has a GIL, so something like this is unnecessary at least in that implementation. You can use a lock for explicit synchronization – Niklas B. Apr 08 '14 at 23:08
  • Thank you, Niklas. I have a lock version of the program, I just want to build a lock-free one and compare the performance. – leeshell Apr 08 '14 at 23:23
  • 2
    Python doesn't have these kinds of low-level primitives because it is an interpreted language. If lock-freeness and performance is of concern, maybe you should use a compiled language – Niklas B. Apr 08 '14 at 23:24
  • 1
    The GIL doesn't make this irrelevant, because Python still has threads (which is why it has a GIL!). But yes, the performance argument is perhaps more true — but in IronPython and Jython where neither has a GIL it obviously matters more, and in PyPy the performance argument is far less true. – gsnedders Jul 22 '15 at 10:35

2 Answers2

2

From the atomics library:

import atomics


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

# set to 5 if a.load() compares == to 0
res = a.cmpxchg_strong(expected=0, desired=5)
print(res.success)

Note: I am the author of this library

doodspav
  • 290
  • 3
  • 11
0

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')
    
  • Please don't copy/paste the same answer on multiple questions. This answer doesn't include an example of using an atomic CAS, only `a.array_sub_and_fetch`. It seems to be a copy/paste of your answer on [python atomic data types](https://stackoverflow.com/a/73884815) . Also, it starts 5000 threads, instead of doing any looping within a thread? That doesn't seem like a good example. – Peter Cordes Sep 28 '22 at 23:04
  • Also cross-posted as [Is set.copy() atomic in Python?](https://stackoverflow.com/a/73885024) and [Is a variable swap guaranteed to be atomic in python?](https://stackoverflow.com/a/73885283) – Peter Cordes Sep 28 '22 at 23:27
  • Pleae use the API shared_atomic.atomic_int.int_compare_and_set(v: _cffi_backend._CDataBase, e: _cffi_backend._CDataBase, n: int) – Xiquan Ren Oct 01 '22 at 01:25
  • [edit] our answer to contain the answer, don't just leave it in comments. – Peter Cordes Oct 01 '22 at 01:33