""" An example of deadlock created by a buyer and seller each insisting that they get what they want (the item or money, respectively) before giving up what they have (the money or item, respectively). Uses a Barrier as a thread-setup step (subclassing Thread and using __init__ for setup would also work). Like all deadlock, this meets all four Coffman conditions: 1. mutual exclusion, because only one can have each asset at a time 2. hold and wait, because they hold their asset while waiting to get the other asset 3. no preemption, because neither can force the other to give up what they have 4. circular wait, because the hold and wait graph looks like this: [buyer] — waiting on → [item] ↑ | held by held by | ↓ [money] ← waiting on — [seller] or, if we use locks as nodes and threads holding one while waiting for another as edges, buyer ————→ [money] [item] ←———— seller """ from threading import Thread, Lock, Barrier b = Barrier(2) item, money = Lock(), Lock() def buyer(item, money, b): money.acquire() # setup step: the buyer starts with money print('Buyer has money, ready for exchange') b.wait() # don't proceed until everyone is set up print('Buyer: "Give me the item first and I promise to pay you"') print('(buyer waiting for item)') item.acquire() print('(buyer has item)') print('Buyer: "Thanks for the item; here is the money"') money.release() print('(buyer no longer has money)') def seller(item, money, b): item.acquire() # setup step: the seller starts with the item print('Seller has item, ready for exchange') b.wait() # don't proceed until everyone is set up print('Seller: "Pay me first and I promise to give you the item"') print('(seller waiting for money)') money.acquire() print('(seller has been paid)') print('Seller: "Thanks for the money; here is the item"') item.release() print('(seller no longer has item)') ts = [Thread(target=buyer, args=(item,money,b)), Thread(target=seller, args=(item,money,b))] for t in ts: t.start() for t in ts: t.join() print('Exchange finished')