Are locks unnecessary in multi-threaded Python code because of the GIL?

前端 未结 9 1103
遥遥无期
遥遥无期 2020-12-02 08:11

If you are relying on an implementation of Python that has a Global Interpreter Lock (i.e. CPython) and writing multithreaded code, do you really need locks at all?

9条回答
  •  囚心锁ツ
    2020-12-02 09:03

    You will still need locks if you share state between threads. The GIL only protects the interpreter internally. You can still have inconsistent updates in your own code.

    For example:

    #!/usr/bin/env python
    import threading
    
    shared_balance = 0
    
    class Deposit(threading.Thread):
        def run(self):
            for _ in xrange(1000000):
                global shared_balance
                balance = shared_balance
                balance += 100
                shared_balance = balance
    
    class Withdraw(threading.Thread):
        def run(self):
            for _ in xrange(1000000):
                global shared_balance
                balance = shared_balance
                balance -= 100
                shared_balance = balance
    
    threads = [Deposit(), Withdraw()]
    
    for thread in threads:
        thread.start()
    
    for thread in threads:
        thread.join()
    
    print shared_balance
    

    Here, your code can be interrupted between reading the shared state (balance = shared_balance) and writing the changed result back (shared_balance = balance), causing a lost update. The result is a random value for the shared state.

    To make the updates consistent, run methods would need to lock the shared state around the read-modify-write sections (inside the loops) or have some way to detect when the shared state had changed since it was read.

提交回复
热议问题