Deadlocks
Deadlock Conditions
- what is deadlock?
- cycle of waiting among as a set of threads, where thread mutually wait on each other to take some action
- necessary conditions for deadlock
- bounded resources: finite instances of a resource
- no preemption: resource held by a thread can't be involuntarily revoked
- hold and wait: a thread holds one resource while waiting for another
- circular wait: a set of waiting threads such that each thread is waiting for a resource held by another
- necessary conditions => can't have a deadlock if one of these conditions isn't true
- but not sufficient
- multiple instances resource
- if each resource can have more than one instance (e.g. # of chopsticks), the 4 conditions are not sufficient for deadlock
- why? what happens if we introduce more instances of the resource into our system?
- single instance resource
- if each resource can only have a single instance (e.g. lock), the 4 conditions are sufficient for deadlock
- dinning philosopher problem
What To Do About Deadlocks
- 3 types of strategy
- prevention
- restructure code, limit behavior of system to eliminate deadlock in your code
- break a necessary condition: sufficient resources, preemption, release and wait, lock ordering
- avoidance
- instead of having the programmers restructure their code, have the system grant access to resources
- system can delay granting resources to avoid execution orders that would lead to a deadlock
- system needs to know the maximum amount of resources each thread needs
- when a thread requests for a resource, the system grants it only if doing so would
- still allow existing threads (including the requesting thread) to eventually acquire their max resources (safe state)
- safe, unsafe, deadlock state
- safe: there is at least one possible execution order that let existing threads have access to their max resources and finish
- unsafe: there's at least one sequence of future requests that will lead to deadlock regardless of the execution order
- future requests: requests the system expects a thread to make before it has reached its maximum resources
- when a thread finishes without making future requests, possible to go from unsafe => safe
- when a thread makes a future request that leads to a deadlock, unsafe => deadlock
- when a thread makes a future request that does not to a deadlock, unsafe => unsafe
- deadlock: has at least 1 deadlock
- detection
- if deadlock is rare, let it happen, just need to detect and recover from it
- detect: graph, algorithm, may have high false positives
- recover: rollback and retry, proceed without resource
- one more strategy: ostrich algorithm
- ignore problem if it's rare
- user can reboot when they are tired of the hanging