Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other...

45
Multithreading and Interactive Programs CS160: User Interfaces John Canny .

Transcript of Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other...

Page 1: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Multithreading and Interactive Programs

CS160: User Interfaces

John Canny

.

Page 2: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Last time

Model-View-Controller

Break up a component into

– Model of the data supporting the App

– View determining the look of the application

– Controller for mediating and event management

Provides scalability and extensibility

Damage-Repair

• A strategy for fast rendering

Page 3: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

This time

Multithreading for interactivity – need and risks

Some design patterns for multithreaded programs

Debugging multithreaded programs

Page 4: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Why Multithreading?

Interactive programs need to respond fast to user input.

Direct manipulation assumes that objects onscreen move with the user’s hand.

Page 5: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Why Multithreading?

But not all code returns from event-handling so fast:

• File access

• Network operations

• Database lookup

• Simulation

Page 6: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Why Multithreading?

We at least need to decouple the code processing screen events from the code that handles them.

But we often need to do more to make sure the code runs robustly, even in the presence of errors.

Page 7: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Why Multithreading?

Other processes that need to stay “live”

• Getting help

• Aborting (need to handle the abort operation)

• Doing something else while waiting for a long operation

Running these modules in a single thread violates several usability heuristics.

Which are they?

Page 8: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Why Multithreading?

More examples:

Multicore processors: use all the CPUs

Dynamic widgets:

• Clocks

• Progress indicators

• Mail inbox…

PS your course projects don’t have to be multi-threaded, they are interactive prototypes.

Page 9: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

What is a Thread?A thread is a partial virtual machine. Each thread has its own

stack, but shares most of memory, i.e. heap space and program memory* with other threads.

for (i=0; i<n; i++) {

tmp = A[i];

A[i] = B[i];

B[i] = tmp;

}

* Threads may also have some private heap space, called Thread-Local Storage (TLS).

VM1 VM2

Page 10: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

What is a Process?

A process is a complete virtual machine with its own stack and heap.

Since processes don’t share memory with each other, they need other mechanisms (e.g. system message queues) to communicate with each other.

Page 11: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Processes vs. Threads

i.e. processes are like dating but multithreaded programs are like living together.

Page 12: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Why Threads?

Because they share memory, threads support very efficient and versatile communication. In fact, such communication is basically free, and any data structure can be used.

Well, even if communication is free, code development certainly isn’t. Multithreaded programming is probably the biggest productivity killer of all time.

Page 13: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Threading Hell

Mutexes

Semaphores Locks

Monitors

Signal()Wait()

Spawn()

Join()

P() V()

Condition Var

Page 14: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Why is it hard?

Threading primitives are lower-level than high-level language constructs.

Not standardized across OSes.

Nondeterminism.

Combinatorics:

Page 15: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Combinatorics

Consider 10 steps of a simple non-branching program.

A = B;

C = 4*A;

Y = exp(C);

Z = 5*R;

There is exactly one way that these statements can execute in a single-threaded program.

Page 16: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Combinatorics

But if two threads execute the same 10 statements, how many possible orderings of operations are there?

A = B;

C = 4*A;

Y = exp(C);

Z = 5*R;

A: 184756 = - but really more since there will be>> 10 instructions in the executable

10

20

Page 17: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Thread Safety

Code is thread safe if it can be called from multiple threads without interaction between them.

A simple C++ function or method works just fine:

int fact (int n) {

int i, p;

for (i=1,p=1; i<=n; i++) p*=i;

return p;

}

Separate ints i,p are created on the stack each time the function is called. Each thread has its own copy.

Page 18: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Thread un-Safety

But what happens if we change the variables to static (shared or global)?

int fact (int n) {

static int i, p;

for (i=1,p=1; i<=n; i++) p*=i;

return p;

}

Page 19: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Thread Safety and OOP

Object-Oriented Programming uses class instances, and these are usually heap-allocated. Heap storage is shared, and so class instances can be seen and manipulated by all threads.

You need to take extra care when writing OOP multi-threaded code for this reason.

Arbitrary sharing of state in objects is very likely to lead to chaos (Windows Vista Explorer crash)

Try to use a well-structured concurrent design pattern, like the ones we are going to describe.

Page 20: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Threading Systems

Posix threads (Pthreads) are available on many systems including gcc and Mac OSX. They support:

pthread_create: create a thread with a function to run

pthread_join: wait for a thread to finish (from outside)

pthread_exit: finish a thread from inside (optional)

Page 21: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Thread Coordination

Data primitives to allow one thread to process data without interference from others.

Include semaphores, mutexes, condition variables, monitors.

These are all low-level constructs and very error-prone.

Objective-C, Java and C# support a “synchronized” block wrapper.

Page 22: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Objective-C @synchronized

The following code snippet protects a segment of code from access by more than one thread:

- (void) setx:(double)x0 {

@synchronized (self) {

x = x0;

}

}

The first thread to execute this obtains a lock (usually a Posixmutex) on the class instance (self).

Another thread will block at the @synchronized statement until the first thread exits this block.

Page 23: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Objective-C @synchronized

- (void) setx:(double)x0 {

@synchronized (self) {

x = x0;

}

}

// Reads or writes wait on self if a read/write is in progress

- (double) x {

double tmp;

@synchronized (self) {

tmp = x;

}

return tmp;

}

Page 24: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Objective-C @synchronized

@synchronized (someObject) {

code;

}

// Expands as

@try {

lock(someObject); // (implementation-dependent).

code; // Exceptions or return might happen here.

}

@finally { // But this happens anyway.

unlock(someObject);

}

Page 25: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Objective-C @synchronized

@synchronized is usually applied to class instances (self), but can also be used to lock a class variable, which locks all methods for that class.

The @synchronized block does the right thing most of the time, and is implementation independent.

Similar constructs exist in Java and C#.

Page 26: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Design Patterns

• Delegate

• Message queue / Dataflow

• Database / Model-View-Controller

• Actor

Page 27: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Delegate

Problem: a “message” is to be executed by calling a class method, but asynchronously. E.g. the message may come from a queue.

We want a persistent piece of data that includes the target (a class instance), the method to call, and possibly other arguments.

Solution: Create a new class that stores a reference to the target class, and has a single member function such as “invoke”.

To use the delegate, we send it an “invoke” message which causes it to call a specific method on its target class.

Page 28: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Delegate

@interface drawer {

id mytarget;

}

- (id) init:(id) t0; // Init the target class

- (void) invoke; // Universal message to do something

@end

Page 29: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Delegate

@implementation drawer;

- (id) init:(id)t0 { // Just create with target class

if (self = [super init]) {

mytarget = t0;

}

return self;

}

- (void) invoke {

[mytarget draw];

}

@end

Page 30: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Delegate

Now we can drop such delegate objects into a queue.

When they pop out, a message handler always calls “invoke” on them.

The appropriate method on the appropriate target class gets called.

They can also be used to implement widget connections ala InterfaceBuilder.

Page 31: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Message Queues

Two threads (or processes) with limited communication can use a message queue.

This is a simple implementation which minimizes coordination and data-sharing between the two threads.

Thread 1

sendmsg(msg);

Thread 2

while (1) {

msg=getevent();

process(msg);

}

Queue

Page 32: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Message Queues

Examples:

• .NET MessageQueue objects

• Thread-specific message queues in the Windows GUI API

• Java Message Service (JMS)

And similar primitives exist between processes:

• POSIX message queues (in Linux)

• CORBA asynchronous messaging

Page 33: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Message Queues

We can realize a message queue by synchronizing queue and dequeue operations in a standard queue. i.e.

@Implementation msgQueue;

- (void) enqueue:(id)arg0

{

@synchronized (self) {

… // enqueue arg0

}

}

Page 34: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Message Queues

We can realize a message queue by synchronizing queue and dequeue operations in a standard queue. i.e.

- (id) dequeue {

id tmp;

@synchronized (self) {

… // dequeue tmp

}

return tmp;

}

Page 35: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Message Queues

Advantages:

• Code is basically sequential in each thread. Much easier to develop and debug.

• Reusable queue libraries do all the hard work.

Disadvantages:

• Inefficient if too much communication, or if complex data structures are passed.

• Need message loop/dispatcher on receiving end – not very modular.

Page 36: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Model-View-Controller

MVC is an excellent pattern for concurrent programming:

State is centralized in the model, no other communication needed

Controllers+Viewers run independently, and each can have its own thread.

Model

View

Controller

View

Controller

View

Controller

Page 37: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Model-View-Controller

Databases provide an excellent backend for the model:

Transactions – complex updates are atomic.

Locking at different scales: an entire table or a row of a table.

Consistency constraints (relations).

Publish-Subscribe

Triggers

Model

View

Controller

View

Controller

View

Controller

Page 38: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

MVC for multithreading

Advantages:

• Extensible, modular.

• Easy to develop and debug.

• Save much coding if a database is used.

Disadvantages:

• Heavy use of resources (space, time, memory).

• Discourages quick information flows.

• Can be very slow with many users if locks are too coarse.

Page 39: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Actor

An actor is a class instance that runs its own thread.

Since data and methods are closely associated in a class, using a single thread to “run” the actor is very modular.

The actor will need an event loop to process incoming events.

Synchronized queues ormailboxes supportcommunication.

Actor 1

while (1) {

msg=getevent();

process(msg);

}

Page 40: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Actor

Advantages:

Easy to design – like the sequential version of the class, but with the event loop added.

Good alignment between threads and data, minimizes contention and probability of inconsistency.

Exploits multicore processors.

Disadvantages:

A system of actors can be very complex to model.

Best to use a mixture of actors and “passive” classes.

A large multi-actor system is resource-intensive (memory, time,…)

Page 41: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Debugging

Not too difficult – similar to sequential debugging with a few extra operations:

Attach: attach the debugger to a running process.

List threads: list the running threads in the program.

Select a thread: Pick one to view or step through.

Thread-specific breakpoints: Stop the program when one specific thread reaches a program line.

Page 42: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Debugging

Note: The debugger normally runs all threads but checks when certain conditions (breakpoints or steps) are met by a particular thread.

So debugged execution is very similar to live execution, except for the pauses.

Page 43: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

e.g. GDB

> attach pid

> i th (info threads)

> th 3

> b MyFile.m:10 thread 3

> c (continue)

> s (step)

> ptype classname

> p varname

> p [self mthd]

> p self->x

> set var x=3

> M-p (meta-p)

attach to a process by its id

show all the running threads

select thread 3

stop program when thrd 3 reaches here

start running

single-step this thread

show a class definition

print a variable value

call a class method

show instance variable value

set a variable to a value

recall last command

Page 44: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Example

The sample program has connections from ButtonStopWatchProgressBar

Button and ProgressBar are widgets, StopWatch is an invisible actor.

Button 1

ProgressBar 1

StopWatch 1on

off

down

up

setv

time

Page 45: Multithreading and Interactive Programsjfc/cs160/F09/lecs/lec12.pdf · Why Multithreading? Other processes that need to stay “live” •Getting help •Aborting (need to handle

Review

Multithreading for interactivity – need and risks

Design patterns for multithreaded programs

• Delegate

• Message queue

• MVC

• Actor

Debugging multithreaded programs