This project shows how deadlock is produced and multiple possible solutions.
STEPS TO AVOID DEADLOCK:
i) Avoid locking multiple mutexes but only 1 mutex if possible ii) After locking mutex, avoid calling user provided funtion (that can access/modify the resource without being locked) iii) If you require to lock more than 1 mutex then try to user API/RAII provided by modern C++ (which are discussed in this project) iv) If you can't use API/RAII mentioned in iii) above then lock the mutexes in the same order.
LOCKING GRANULARITY: i) Fine-grained lock: - lock small amount of data, - more complexity, - more prone to deadlock, - achieve more parallel computing i.e. less waiting for mutex ii) Coarse-grained lock: - lock large amount of data, - less complexity, - less prone to deadlock, - achieve less parallel computing i.e. more waiting for mutex
ENCLOSED FILES:
- DeadLockProducer.cpp - Shows how deadlock is produced
DEADLOCK AVOIDANCE TECHNIQUES :
- DeadLockSolution1.cpp - Deadlock avoidance by following locking hierarchy manually
- DeadLockSolution2.cpp - Deadlock avoidance by using std::lock() and std::lock_guard
- DeadLockSolution2.cpp - Deadlock avoidance by using std::lock() and std::unique_lock
- DeadLockSolution2.cpp - Deadlock avoidance by using C++17 - std::scoped_lock() - RAII and lock in one go.
TEST RESULTS: Test results for all cases are attached