Please work out these problems before your next discussion section. The GSIs will go over these problems during the discussion section.
You have learned the four necessary conditions for deadlock:
Deadlock prevention schemes work by attempting to remove one (or more) of these conditions. In this homework, you will look at two such methods.
You are developing a multithreaded bank software package. Suppose you have a method for transferring funds from one account to another. Each user account has a lock associated with it.
You must acquire the lock for both accounts before transferring funds, to ensure the money transfer is atomic. The transfer function prototype is:
transfer_money( int from_account_id, int to_account_id, int amount );
Here is an incorrect solution:
/* * An array of locks that ranges over account numbers. * locks[i] = lock for account i */ vectorFor example, thread 1 could execute transfer_money(1, 2, 20), and thread 2 could execute transfer_money(2, 1, 100).locks; void transfer_money(int acct1, int acct2, int amount) { thread_lock(locks[acct1]); thread_lock(locks[acct2]); <transfer money> thread_unlock(locks[acct2]); thread_unlock(locks[acct1]); }
Rewrite transfer_money() to be deadlock-free, by making a circular wait impossible. (Hint: define an ordering for the locks.)
Rewrite transfer_money() again, this time avoiding any possible deadlock by removing the hold-and-wait condition. (Hint: each thread should either acquire both locks at once, or not at all). You may define new shared variables and/or new locks and condition variables. Your solution should not busy-wait.