mutex
mutex.hh
Critical Section
livelock
Multithreading in Windows
thread.hh
pthread.h
Pthread
pthread_setschedparam(pthread_self(), SCHED_OTHER, &sched);
struct Grabber_thread : Thread {
virtual void *thread_run()
io_thread.start();
thread safe
preemptive threading
context switch
event thread: causing the event thread to block for any length of time is considered bad programming practice. (unresponsive application)
Thread Synchronization
Monitors:
A monitor is a set of routines that are protected by a mutual exclusion lock.
A thread cannot execute any of the routines in the monitor until it acquires the lock, which means that only one thread at a time can execute within the monitor,
all other threads must wait for the currently executing thread to give up control of the lock.
Monitor is simpler to use.
Semaphores (mutex): A semaphore is a simpler construct, just a lock that protects a shared resource.
counting semaphores
event semaphore
Deadlock
Deadlock avoidance
Java:
public synchronized boolean deposit( double amount ) { }
public synchronized boolean withdraw( double amount) { }
or
synchronized(this) {
}
C#:
lock(this) {
.... //the code to protect, only within a method.
}
busy waiting
Java:
Thread task = new TheTask();
task.start();
while( task.isAlive() ) {
; // do nothing
}
Solution (shared object):
Object theLock = new Object(); //shared object
synchronized( theLock) {
Thread task = new TheTask( theLock );
task.start();
try {
theLock().wait();
}
catch (InterruptdException e) {
..... // do something if interrupted.
}
} //end of theLock
............
class TheTask extends Thread {
private Object theLock;
public TheTask( Object theLock) {
this.theLock = theLock;
}
public void run() {
synchronized ( theLock) {
....//do the task.
theLock.notify();
}
}
} //end of TheTask
///////////////////////////////////////////////////////
//The code can be simplified as:
///////////////////////////////////////////////////////
Thread task = new TheTask();
synchronized( task) {
task.start();
try {
task.wait();
}
catch ( InterruptedException e) {
.......//do something if interrupted
}
....................
class TheTask extends Thread {
public void run() {
synchronized( this ) {
.... // do the task.
this.notify();
}
}
} //end of TheTask
Producer/Consumer (java)
public class IntBuffer {
private int index;
private int[] buffer = new int[10];
public synchronized void add( int num ) {
while(index == buffer.length-1) {
try {
wait();
}
catch(InterruptedException e) {
}
} //end of while
buffer[index]=num; index++;
notifyAll();
}
public synchronized int remove() {
while(index == 0) {
try {
wait();
}
catch (InterruptedException e) {
}
} // end while
index --;
int ret = buffer[index];
notifyAll();
return(ret);
} //end of remove
} //end of class
public class Producer extends Thread {
private Intbuffer buffer;
public Producer( IntBuffer buffer) {
this.buffer = buffer;
}
public void run() {
Random r = new Random();
while(true) {
int num = r.nextInt();
buffer.add(num);
System.out.println("Produced " + num);
}
}
}
public class Consumer extends Thread {
private IntBuffer buffer;
public Consumer (IntBuffer buffer) {
this.buffer = buffer;
}
public void run() {
while (true) {
int num = buffer.remove();
System.out.println("Consumed " + num);
}
}
}
IntBuffer b = new IntBuffer();
Producer p = new Producer(b);
Consumer c = new Consumer(b);
p.start();
c.start();
The Dining Philosophers
public class DiningPhilosophers {
//each fork is just an Object we synchronize on
private Object[] forks;
private Philosopher[] philosophers;
private DiningPhilosophers (int num) {
forks = new Object[num];
philosophers = new philosopher[num];
for (int i = 0; i
int fork1 = i;
int fork2 = (i+1) % num;
if(i==0) //philosopher 0 picks up fork2 first.
philosophers[0] = new Philosopher( i, fork2, fork1 );
else
philosophers[i] = new Philosopher( i, fork1, fork2 );
}
}
public void startEating() throws InterruptedException {
for (int i =0; i < id="iv3o"> philosophers[i].start();
}
//suspend the main thread until the first philosopher stops eating, which will never happen
//this keeps the simulation running indefinitely
philosophers[0].join();
} //end startEating
private class Philosopher extends Thread {
private int id;
private int fork1;
private int fork2;
Philosopher (int id, int fork1, int fork2) {
this.id =id;
this.fork1 = fork1;
this.fork2 = fork2;
}
public void run() {
status("Ready to eat using forks "+fork1+ " and "+fork2);
pause(); //pause to let others get ready.
while(true) {
status("Picking up fork "+fork1);
synchronized ( forks[fork1]) {
status("Picking up fork "+fork2);
synchronized ( forks[fork2]) {
status("Eating");
} //fork2
} //fork1
} //while
} //end run
private void pause() {
try {
sleep(300);
}
catch ( InterruptedException e) {
//do nothing
}
}
private void status ( String msg) {
System.out.println("Philosopher " + id + ": " + msg);
}
} //end of philosopher
public static void main(String[] args) {
try {
DiningPhilosophers d = new DiningPhilosophers(5);
d.startEating();
}
catch ( InterruptedException e) {
}
} //end main
}
Multi-Threaded Programming With POSIX Threads(good tutorial)
Win32 Multithreaded Programming, Aaron Cohen and Mike Woodring, 1998
Errata and Source Code
Mike Woodring's .NET Sample Page
No comments:
Post a Comment