Solving deadlock in python using multiprocessing subprocess?

Question:

College assignment requested that we modify the code below to stop it from deadlocking, without changing the main function.

Right now, it is deadlocking because of how the locks end up waiting for each other. My professor mentioned using os.fork, which is not possible as I am using a Windows machine.

import threading
x = 0

def task(lock1, lock2, count):
    global x
    for i in range(count):
        lock1.acquire()
        lock2.acquire()
        # Assume that a thread can update the x value
        # only after both locks have been acquired.
        x+=1
        print(x)
        lock2.release()
        lock1.release()

# Do not modify the main method
def main():
    global x
    count = 1000
    lock1 = threading.Lock()
    lock2 = threading.Lock()
    T1 = threading.Thread(target = task, args = (lock1, lock2, count))
    T2 = threading.Thread(target = task, args = (lock2, lock1, count))

    T1.start()
    T2.start()
    T1.join()
    T2.join()
    print(f"x = {x}")

main()
Asked By: Adin D

||

Answers:

Your threads need to lock the locks in a consistent order. You can do this by locking the one with the lower id value first:

def task(lock1, lock2, count):
    global x
    if id(lock1) > id(lock2):
        lock1, lock2 = lock2, lock1
    for i in range(count):
        lock1.acquire()
        lock2.acquire()
        # Assume that a thread can update the x value
        # only after both locks have been acquired.
        x+=1
        print(x)
        lock2.release()
        lock1.release()

With a consistent lock order, it’s impossible for two threads to each be holding a lock the other needs.

(multiprocessing, subprocess, and os.fork are all unhelpful here. They would just add more issues.)

Answered By: user2357112