Is a variable swap guaranteed to be atomic in python?

后端 未结 2 769
孤城傲影
孤城傲影 2020-12-03 04:39

With reference to the following link: http://docs.python.org/faq/library.html#what-kinds-of-global-value-mutation-are-thread-safe

I wanted to know if the following:<

2条回答
  •  一生所求
    2020-12-03 05:19

    Let's see:

    >>> x = 1
    >>> y = 2
    >>> def swap_xy():
    ...   global x, y
    ...   (x, y) = (y, x)
    ... 
    >>> dis.dis(swap_xy)
      3           0 LOAD_GLOBAL              0 (y)
                  3 LOAD_GLOBAL              1 (x)
                  6 ROT_TWO             
                  7 STORE_GLOBAL             1 (x)
                 10 STORE_GLOBAL             0 (y)
                 13 LOAD_CONST               0 (None)
                 16 RETURN_VALUE    
    

    It doesn't appear that they're atomic: the values of x and y could be changed by another thread between the LOAD_GLOBAL bytecodes, before or after the ROT_TWO, and between the STORE_GLOBAL bytecodes.

    If you want to swap two variables atomically, you'll need a lock or a mutex.

    For those desiring empirical proof:

    >>> def swap_xy_repeatedly():
    ...   while 1:
    ...     swap_xy()
    ...     if x == y:
    ...       # If all swaps are atomic, there will never be a time when x == y.
    ...       # (of course, this depends on "if x == y" being atomic, which it isn't;
    ...       #  but if "if x == y" isn't atomic, what hope have we for the more complex
    ...       #  "x, y = y, x"?)
    ...       print 'non-atomic swap detected'
    ...       break
    ... 
    >>> t1 = threading.Thread(target=swap_xy_repeatedly)
    >>> t2 = threading.Thread(target=swap_xy_repeatedly)
    >>> t1.start()
    >>> t2.start()
    >>> non-atomic swap detected
    

提交回复
热议问题