Why do we need locks for threads, if we have GIL?

前端 未结 4 1746
心在旅途
心在旅途 2021-01-31 15:53

I believe it is a stupid question but I still can\'t find it. Actually it\'s better to separate it into two questions:

1) Am I right that we could have a lot of threads

4条回答
  •  陌清茗
    陌清茗 (楼主)
    2021-01-31 16:28

    At any moment, yes, only one thread is executing Python code (other threads may be executing some IO, NumPy, whatever). That is mostly true. However, this is trivially true on any single-processor system, and yet people still need locks on single-processor systems.

    Take a look at the following code:

    queue = []
    def do_work():
        while queue:
            item = queue.pop(0)
            process(item)
    

    With one thread, everything is fine. With two threads, you might get an exception from queue.pop() because the other thread called queue.pop() on the last item first. So you would need to handle that somehow. Using a lock is a simple solution. You can also use a proper concurrent queue (like in the queue module)--but if you look inside the queue module, you'll find that the Queue object has a threading.Lock() inside it. So either way you are using locks.

    It is a common newbie mistake to write multithreaded code without the necessary locks. You look at code and think, "this will work just fine" and then find out many hours later that something truly bizarre has happened because threads weren't synchronized properly.

    Or in short, there are many places in a multithreaded program where you need to prevent another thread from modifying a structure until you're done applying some changes. This allows you to maintain the invariants on your data, and if you can't maintain invariants, then it's basically impossible to write code that is correct.

    Or put in the shortest way possible, "You don't need locks if you don't care if your code is correct."

提交回复
热议问题