110 likes | 223 Views
CSC 580 - Multiprocessor Programming, Spring, 2011. Chapter 10 – Avoiding Liveness Hazards Dr. Dale E. Parson, week 11. Deadlock. Deadly embrace -- multiple threads block waiting for resources held by other threads blocked waiting for resources in a cyclic dependency on those resources.
E N D
CSC 580 - Multiprocessor Programming, Spring, 2011 Chapter 10 – Avoiding Liveness Hazards Dr. Dale E. Parson, week 11
Deadlock • Deadly embrace -- multiple threads block waiting for resources held by other threads blocked waiting for resources in a cyclic dependency on those resources. • Cycle of lock requests. • Some worker threads from assignment 2 enter the CountDownLatch while others enter the CyclicBarrier. • A cyclic dataflow dependency such as PipedOutput/Input streams in a signal feedback loop. • Other similar + combinations of above.
Lock ordering • A program will be free of lock-ordering deadlocks if all threads acquire the locks they need in a fixed global order. (p. 206) • Likewise for other blocking resources. • Induce an ordering on dynamically determined locks. • System.identityHashCode typically returns a unique integer for every unique object. Use it to sort / order multiple dynamic locks. • In case of a tie (collision), introduce a tie-breaker lock that must be acquired first. • Requires knowing the set of locks at one time.
Hold locks for minimal time • Invoking an alien method (method outside of the object managing a lock) with a lock held is asking for liveness trouble. The alien method might acquire other locks (risking deadlock) or block for an unexpectedly long time, stalling other threads that need the lock. (p. 211) • Try to organize interrelated data @GuardedBy a lock so you can prepare to manipulate that data, then acquire the lock, manipulate the data, and release the lock as soon as possible, without invoking unbounded alien methods.
Open calls • Classes that rely on open calls (calls made with no locks held) are better behaved and composable than classes that make calls with locks held. (p. 211) • Liveness analysis that relies exclusively on open calls is easier than one that does not. • Loss of atomicity may be a problem. • Use a thread interaction protocol that manages critical sections while minimizing locking.
Thread starvation deadlock • Tasks that wait for results of other tasks are the primary source. (p. 215) • Bounded pools and interdependent tasks do not mix well. • Suppose you have a data flow that requires N concurrent tasks in order not to freeze up waiting for work, but your thread pool supports < N tasks.
Thread-starved example from midterm public boolean guardedAdd(IntegerPredicate guard, int incr) { boolean result = false ; while (! result) { // Do not let an interleaved change that preserves the int original = counter.get(); // guard condition cause a failure. if (guard.isSatisfied(original)) { result = counter.compareAndSet(original, origina+incr); } else { break ; } } return result ; } // Starvation if guard always met but value always changes concurrently.
Non-starved example from midterm private final AtomicLong getTicket = new AtomicLong(0L); private final AtomicLong callTicket = new AtomicLong(0L); public boolean guardedAdd(IntegerPredicate guard, int incr) { boolean result = false ; long myticket = getTicket .getAndIncrement() while (myticket != callTicket.get()) { } if (guard.isSatisfied(counter)) { // counter is a volatile int here counter += incr ; result = true ; } callTicket.incrementAndGet(); return result ; }
Avoiding and diagnosing deadlocks • Perform global lock analysis, eliminate cycles. • Use timed locks. • Why did timeout occur? Deadlock? Infinite loop bug? Time consuming action? • If multiple locks are acquired in sequence in the same place in code, it is possible to release the predecessor lock(s) (perhaps the full set), back off and wait, then try again. • This approach is nondeterministic but it may work statistically over a large number of attempts. • Ethernet (bus) uses an exponential backoff algorithm. • Solution must include reducing contention for resources.
Thread dumps • SIGQUIT (kill -3) on Unix. • Ctrl-\ on Unix, Crtl-Break on Windows. • Thread dump includes stacks traces and deadlock information. • Explicit locks do not show up in Java 5 thread dumps.
Other liveness hazards • Starvation • Thread priority is a scheduling hint. • Avoid using thread priorities, which may lead to priority inversion and suboptimal scheduling. • Poor performance due to poor workload partitioning (Amdahl’s Law in upcoming chapter) or by holding locks too long. • Livelock means a running thread cannot progress. • Starved thread on slide 7 or a transaction system that always restarts. • Retry with random waits and backoffs.