16
CSC 480 - Multiprocessor Programming, Spring, 2012 Chapter 7 – Cancellation & Shutdown Dr. Dale E. Parson, week 9-10

CSC 480 - Multiprocessor Programming, Spring, 2012

Embed Size (px)

DESCRIPTION

CSC 480 - Multiprocessor Programming, Spring, 2012. Chapter 7 – Cancellation & Shutdown Dr. Dale E. Parson, week 9-10. Task cancellation. Activity is cancellable if external code can move it to completion before normal completion. (p. 135) Server or similar non-terminating activity. - PowerPoint PPT Presentation

Citation preview

Page 1: CSC 480 - Multiprocessor Programming, Spring, 2012

CSC 480 - Multiprocessor Programming, Spring, 2012

Chapter 7 – Cancellation & ShutdownDr. Dale E. Parson, week 9-10

Page 2: CSC 480 - Multiprocessor Programming, Spring, 2012

Task cancellation

• Activity is cancellable if external code can move it to completion before normal completion. (p. 135)

• Server or similar non-terminating activity.• Long-running computation.• Cancellable implies asynchronous notification.

– User-requested cancellation.– Time-limited activities.– Application events (e.g., first solution stops others).– Errors (e.g., file server backing database goes off line).– Shutdown.

Page 3: CSC 480 - Multiprocessor Programming, Spring, 2012

Interruption

• Thread.currentThread() gets current thread.• interrupt() interrupts a thread object.

• Asynchronous but not preemptive.

• isInterrupted() returns some thread’s status without changing it.

• Thread.interrupted() returns current thread’s interrupt status and clears it.

• InterruptedException thrown by many blocking methods. Thrower may clear interrupted status.

Page 4: CSC 480 - Multiprocessor Programming, Spring, 2012

Interruption for cancellation

• Calling interrupt() merely delivers a message.• Using interruption for anything but cancellation is

fragile and difficult to sustain in larger applications. (p. 138)

• Interruption is usually the most sensible way to implement cancellation. (p. 140)

• The intent is that threads running application tasks will have periodic opportunities to notice the interruption message, and know what that means.

Page 5: CSC 480 - Multiprocessor Programming, Spring, 2012

Cancellation & Interruption Policy

• A Cancellation Policy is a plan for how an algorithm quits in the middle of its work.

• An Interruption Policy is a plan for how application threads and tasks respond to interrupt messages.

• Interruption is ultimately under the control of the application framework.• The design of an application framework must establish

how it uses interrupts to communicate with tasks.

Page 6: CSC 480 - Multiprocessor Programming, Spring, 2012

Responding to an interrupt

• Do not interrupt() a thread unless you know its interruption policy. Interruption typically comes from elsewhere in application code.

• Library and application-neutral framework code may neither interpret nor ignore InterruptedException.

• A library method may throw the InterruptedException.• A library method may re-call interrupt() on its thread.

• Application code must handle the interrupt.• Use the cancellation and interruption policy to direct control.• Swallow InterruptedException only if that works with the policies.

Page 7: CSC 480 - Multiprocessor Programming, Spring, 2012

Task Cancellation

• Tasks run in frameworks, e.g., ExecutorService.• submit() returns a Future; it may be cancel()d.• cancel() has mayInterruptIfRunning param.• The application-level task, if running, must

decide what to do with the optional interrupt.• Future.get throws CancellationException or

ExecutionException for abnormal termination of its task. Latter carries its original cause.

Page 8: CSC 480 - Multiprocessor Programming, Spring, 2012

Uninterruptible I/O

• InputStream.read and OutputStream.write do not throw InterruptedException.

• Calls may block indefinitely.• close() on the underlying stream from another thread

causes IOException, but it may be dangerous.• Sending a “Poison pill” (special sentinel value) into the

stream from another thread, if possible, is safer.

• java.nio and java.nio.channels.Selectors have related issues, also support for closed-by-interrupt exceptions. See Javadoc.

Page 9: CSC 480 - Multiprocessor Programming, Spring, 2012

Uninterruptible lock acquisition

• Explicit lock has lockInterruptibly(), but lock() and implicit synchronized locks are uninterruptible.

• If there is no cyclic dependency among locks (which leads to deadlock), the thread holding the lock must make progress, possibly via interruption, and release the lock.

• Compute-bound tasks or tasks that invoke non-interruptible methods, and that have an interruption policy, may need to poll isInterrupted() periodically.

Page 10: CSC 480 - Multiprocessor Programming, Spring, 2012

Stopping a thread-based service

• Lifecycle methods of the service are necessary for state transitions and termination.

• The thread pool that manages the worker threads decides whether and when to interrupt them.

• The application code running in the service threads decides how to respond to interruption (policy).

• ExecutorService.shutdown• shutdown() – previously submitted tasks are executed, but no new

submissions are accepted.• shutdownNow() attempts to terminate tasks (typically via

interrupt()) and returns a list of tasks that were awaiting execution.

Page 11: CSC 480 - Multiprocessor Programming, Spring, 2012

Poison pill

• Poison pill is a sentinel value that a producer passes to consumer(s) to signal shutdown.

• Poison pill(s) must come after all regular producer application data.• From solution #1 Input.run():

if (myburst.isEmpty()) { int remaining = pktq.decrementAndGetInputs(); if (remaining == 0) { // I was the last Input thread, send a sentinel to each // output thread. int outputcount = pktq.getOutputs(); for (int i = 0 ; i < outputcount ; i++) { pktq.enqueue(myburst); // empty list is sentinel } } return ; }

Page 12: CSC 480 - Multiprocessor Programming, Spring, 2012

Limitations of shutdownNow

• There is no option to cancel un-started tasks while allowing started tasks to complete.

• It is possible to extend or adapt ExecutorService to interact with tasks in an application-specific way to determine which tasks are started without completion, and to stop only the unstarted ones. See 7.2.5.

• Race condition at task completion time is still likely.

Page 13: CSC 480 - Multiprocessor Programming, Spring, 2012

Abnormal thread termination

• Possible to log a stack trace, but general purpose thread pool library classes do not own the application logs.

• Printing stack traces to System.err may be lost.

• General purpose framework (e.g., Eclipse) may catch unchecked exceptions (RuntimeException) and display a warning about the suspect integrity of the compromised application task or plug-in.

Page 14: CSC 480 - Multiprocessor Programming, Spring, 2012

Boilerplate code for dealing with untrusted tasks (p. 162)

public void run() {Throwable thrown = null ;try {

while (! currentThread().isInterrupted()) {runTask(getTaskFromWorkQueue()); }

} catch (Throwable e) {thrown = e ;

} finally {threadExited(this, thrown);

}}

Page 15: CSC 480 - Multiprocessor Programming, Spring, 2012

JVM shutdown and Daemon threads

• Runtime.addShutdownHook() deals with cases where a thread invokes System.exit() or a terminating signal arrives from the O.S.

• It starts a series of registered threads.• Make these thread-safe, defensive, and conservative.

• Daemon threads are never joined to the main thread. Text advises to use them sparing, perform no I/O in them. Use them for housekeeping such as managing an in-memory cache.

Page 16: CSC 480 - Multiprocessor Programming, Spring, 2012

Finalizers

• Object.finalize() runs when the garbage collector is about to recover an object.

• Test says: “Avoid finalizers.”• Explicit try-finally blocks that close() (and

flush) output resources are safer and easier than using finalizers.

• They may be necessary for freeing resources obtained by native methods.