Syllabus | Blank | Homework | ||
Notes | Labs | Scores | Blank |
The top software developers are more productive than average software developers not by a factor of 10X or 100X or even 1000X but by 10,000X. Nathan MyhrvoldReview and Overview
wait: | down ( mutex ); |
access_CS(); | |
signal: | up ( mutex ); |
C-code | Guarded Commands |
---|---|
void wait ( int S ) { //atomic while ( S <= 0 ) ; //wait S = S - 1; } |
when ( S > 0 ) [
S = S - 1; ]
when ~ guard
|
void signal ( int S ) { //atomic S = S + 1; } | [ S = S + 1; ] |
Weakness
public class Score { private double score; private double total; public synchronized void setScore ( double s ) { score = s; } public synchronized void addScore ( double s ) { total += s; } public double getScore () { return score; } ..... }
Guarded Command | Java Implementation |
---|---|
when ( guard ) [ statement 1 ..... statement n ] |
class SharedResource { final Lock mutex = new ReentrantLock(); final Condition condVar = mutex.newCondition(); boolean condition = false; ..... public void methodA() throws InterruptedException { mutex.lock(); while ( !condition ); condVar.await(); statement 1 ..... statement n mutex.unlock(); } ..... } |
//code modifying guard ..... |
class SharedResource { ..... public void methodB() throws InterruptedException { mutex.lock(); condition = true; //or code modifying guard ..... condVar.signal(); mutex.unlock(); } } |
void reader() { when ( writers == 0 ) [ readers++; ] //read [readers--;] } |
void writer() { when ( (readers == 0) && (writers == 0) )[ writers++; ] //write [writers--;] } |
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class ReaderWriter { final Lock mutex = new ReentrantLock(); final Condition readerQueue=mutex.newCondition(); //cond variable final Condition writerQueue=mutex.newCondition(); //cond variable int nReaders = 0; //number of reader threads int nWriters = 0; //number of writer threads (0 or 1) void reader() throws InterruptedException { mutex.lock(); //mutual exclusion while ( !(nWriters == 0) ) readerQueue.await();//wait in readerQueue till no more writers nReaders++; //one more reader mutex.unlock(); //read //........ //finished reading mutex.lock(); //need mutual exclusion if ( --nReaders == 0 ) writerQueue.signal();//wake up a waiting writer mutex.unlock(); } void writer() throws InterruptedException { mutex.lock(); while ( !((nReaders == 0) && (nWriters == 0)) ) writerQueue.await();//wait in writerQueue // until no more writer & readers nWriters++; //one writer mutex.unlock(); //write //........ //finished writing mutex.lock(); //need mutual exclusion nWriters--; //only one writer at a time writerQueue.signal(); //wake up a waiting writer readerQueue.signalAll(); //wake up all waiting readers mutex.unlock(); } } |
void reader() { when ( writers == 0 ) [ readers++; ] //read [readers--;] } |
void writer() { [writers++;] when ( (readers == 0) && (active_writers == 0) )[ active_writers++; ] //write [writers--; active_writers--;] } |
class ReaderWriterPriority { final Lock mutex = new ReentrantLock(); final Condition readerQueue = mutex.newCondition(); //cond variable final Condition writerQueue = mutex.newCondition(); //cond variable int nReaders = 0; //number of reader threads int nWriters = 0; //number of writer threads (0 or 1) int nActiveWriters = 0; //number of threads currently writing void reader() throws InterruptedException { mutex.lock(); //mutual exclusion while ( !(nWriters == 0) ) readerQueue.await(); //wait in readerQueue until no more writers nReaders++; //one more reader mutex.unlock(); //read //........ //finished reading mutex.lock(); //need mutual exclusion if ( --nReaders == 0 ) writerQueue.signal();//wake up a waiting writer mutex.unlock(); } void writer() throws InterruptedException { mutex.lock(); nWriters++; //a writer has arrived while ( !((nReaders == 0) && (nActiveWriters == 0)) ) writerQueue.await(); //wait in writerQueue // until no more writer & readers nActiveWriters++; //one active writer mutex.unlock(); //write //........ //finished writing mutex.lock(); //need mutual exclusion nActiveWriters--; //only one active writer at a time if ( --nWriters == 0 ) //no more waiting writers, so wake readerQueue.signalAll();// up all waiting readers else //has waiting writer writerQueue.signal();//wake up one waiting writer mutex.unlock(); } } |
Weakness:
Procedures |
Hollow Region( multiple processes can be active here ) |
|
Hollow Region( multiple processes can be active here ) |
|
e.g. path write + { read } end
either write or several read
e.g. path { write ; read } end
at any time, there can be any number of instantiations of
path write; read.
Example: readers-writers problem with weak reader's priority ( several readers can read file at the same time but only one writer can write to the file at a time; an arriving reader has higher priority than a waiting writer if reading has occurred, but when reading or writing is done, reader and writer have same priority, i.e. chosen randomly )
Example: Writer's priority: (when there is more than one path expression, the order of operations indicated by all the path expressions must be satisfied.
Output command = <destination process id> ! <expression>
operators: ! (send) ? (receive)
Usage:
Concurrent processes :
[process P1's code||process P2's code||
..... ||process Pn's code]
Guarded Command
basically :
if ( G )
CL
evaluate G, if false, ( i.e. guard fails ), CL won't be evaluated
Alternative command
Repetitive command
CSP parallelism, on its own, does not introduce non-determinism.
Example
start with i = 0, then repetitively scan until either i ≥ size or some content( i ) equals n
Example
Repeatedly send process P2 a character received from process P1 until P1 terminates.