Reputation: 1275
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.
Upvotes: 0
Views: 205
Reputation: 198456
Your code can deadlock (it did for me on at least one run), but it depends on the one thread executing with resource
between the time the other thread's two with resource
statements.
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 thread1
executes with resource1
completely, thread2
executes with resource2
completely, before the second set of with resource
is executed, it is a deadlock, GIL or no GIL.
If this specific timing does not happen, your code will not deadlock. For example, if thread1
manages to get through both of its with resource
statements without the control being passed to thread2
, 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 two with resource
statements in each function. It doesn't change the logic in any way, but it will make sure that the first set of with resource
statements is executed before the second set, triggering the deadlock situation.
Upvotes: 2