Deadlock question 19.5 in elements of programming interviews

Viewed 190

This question from elements of programming interviews claims there is a deadlock in the following code in the scenario where "U1 initiates a transfer to U2 and immediately afterwards U2 initiates a transfer to U1. Since each transfer takes place in a separate thread its possible for the first thread to lock U1 and then the second to lock U2"

class Account:
    _global_id = 0

    def __init__(self, balance):
        self._balance = balance
        self._id = Account._global_id
        Account._global_id += 1
        self._lock = threading.RLock()

    def get_balance(self):
        return self._balance

    @staticmethod
    def transfer(acc_from, acc_to, amount):
        th = threading.Thread(target=acc_from._move, args=(acc_to, amount))
        th.start()

    def _move(self, acc_to, amount):
        with self._lock:
            if amount > self._balance:
                return False
            acc_to._balance += amount
            self._balance -= amount
            print('returning True')
            return True

I do not see how there is a deadlock in that case. U1 and U2 have separate locks and as far as I can tell, thread1 just locks U1 and thread2 locks U2 since the _move method just uses self._lock and doesn't touch acc_to._lock. What am I missing?

1 Answers

I had the same doubt and did not find a known error on the book's website. Based on the explanation of deadlock in the section before this problem, I think it should be

def _move(self, acc_to, amount):
        with self._lock, acc_to._lock:

instead of

def _move(self, acc_to, amount):
        with self._lock:

since that's the primary way deadlock will occur.

Related