python: With GIL, is it still possible to have deadlocks with threading? (Not multi-processing)
Below code will produce deadlock situation (Updated per Amadan, added sleep):
import threading
import time
# Two resources
resource1 = threading.Lock()
resource2 = threading.Lock()
def function1():
with resource1:
print("Thread 1 acquired resource 1")
time.sleep(3)
with resource2:
print("Thread 1 acquired resource 2")
time.sleep(3)
def function2():
with resource2:
print("Thread 2 acquired resource 2")
time.sleep(3)
with resource1:
print("Thread 2 acquired resource 1")
time.sleep(3)
# Create two threads
thread1 = threading.Thread(target=function1)
thread2 = threading.Thread(target=function2)
# Start the threads
thread1.start()
thread2.start()
# Wait for both threads to finish
thread1.join()
thread2.join()
print("Both threads finished execution")
But conceptually, even with GIL, the two threads can still trying to acquire a lock/resource that's already been acquired by the other thread.
Your code can deadlock (it did for me on at least one run), but it depends on the one thread executing
with resourcebetween the time the other thread's twowith resourcestatements.GIL cannot prevent this deadlock. All it does is says Python can't execute more than one thread's Python code at a time. However, if
thread1executeswith resource1completely,thread2executeswith resource2completely, before the second set ofwith resourceis executed, it is a deadlock, GIL or no GIL.If this specific timing does not happen, your code will not deadlock. For example, if
thread1manages to get through both of itswith resourcestatements without the control being passed tothread2, you're safe. Obviously, if the code has any chance of deadlock, it is bad code, but it is not that easy to notice it since it is so dependent on timing, and so, chance.To make the deadlock a certainty, try to put
time.sleep(1)between the twowith resourcestatements in each function. It doesn't change the logic in any way, but it will make sure that the first set ofwith resourcestatements is executed before the second set, triggering the deadlock situation.