Outline • Announcements • High Level Synchronization Constructs – Simultaneous semaphores – Monitors • Conditional variables • Inter-process Communication Announcements • The schedule for this week and next week – There will be no class this Thursday • Remember that you may need to demonstrate your program during the class time – This Wednesday I will give a make-up lecture – On Oct. 21 we will have a review • Homework #3 is due at the beginning of class so that solutions will be made available during class • Note that no late submission will be accepted for Homework #3 – On Oct. 23 we will have the midterm • The midterm covers chapters 1-9 5/29/2016 COP4610 2 Announcements • About the second quiz – Most of you did well – However, some of you did poorly – Please make sure that you put efforts now if we want to earn a good / passing grade • A preview of the last programming assignment 5/29/2016 COP4610 3 The Dining Philosophers 5/29/2016 COP4610 4 First Try Solution philosopher(int i) { while(TRUE) { // Think // Eat P(fork[i]); P(fork[(i+1) mod 5]); eat(); V(fork[(i+1) mod 5]); V(fork[i]); } } semaphore fork[5] = (1,1,1,1,1); fork(philosopher, 1, 0); fork(philosopher, 1, 1); fork(philosopher, 1, 2); fork(philosopher, 1, 3); fork(philosopher, 1, 4); 5/29/2016 COP4610 5 Nesting Semaphore Operations pr P Operation Order P(mutex1); P(mutex2); <access R1>; <access R2>; V(mutex2); V(mutex1); (a) 5/29/2016 ps P Operation Order P(mutex2); P(mutex1); <access R1>; <access R2>; V(mutex1); V(mutex2); (b) COP4610 6 Simultaneous Semaphores • The orders of P operations on semaphores are critical – Otherwise deadlocks are possible • Simultaneous semaphores – Psimultaneous(S1, ...., Sn) – The process gets all the semaphores or none of them 5/29/2016 COP4610 7 Simultaneous Semaphores 5/29/2016 COP4610 8 A Solution philosopher(int i) { while(TRUE) { // Think // Eat } Psim(fork[i],fork[(i+1) mod 5]); eat(); Vsim(fork[i],fork[(i+1) mod 5]); } semaphore fork[5] fork(philosopher, fork(philosopher, fork(philosopher, fork(philosopher, fork(philosopher, 5/29/2016 = (1,1,1,1,1); 1, 0); 1, 1); 1, 2); 1, 3); 1, 4); COP4610 9 Monitors • High-level synchronization construct that allows the safe sharing of an abstract data type among concurrent processes. class monitor { variable declarations semaphore mutex = 1; public P1 :(…) { P(mutex); ........ V(mutex); }; ........ } 5/29/2016 COP4610 10 Monitors – cont. • To allow a process to wait within the monitor, a condition variable must be declared, as condition x, y; • Condition variable can only be used with the operations wait and signal. – The operation x.wait; means that the process invoking this operation is suspended until another process invokes x.signal; – The x.signal operation resumes exactly one suspended process. If no process is suspended, then the signal operation has no effect. 5/29/2016 COP4610 11 Monitors – cont. 5/29/2016 COP4610 12 Conditional Variables in UNIX • POSIX conditional variables – pthread_cond_wait – pthread_cond_signal • Solaris conditional variables – cond_wait – cond_signal 5/29/2016 COP4610 13 Bounded buffer monitor monitor BoundedBufferType { private: BufferItem * buffer; int NumberOfBuffers; int next_in, nextout; int current_size; condition NotEmpty, NotFull; public: BoundedBufferType( int size ) { buffers = new BufferItem[size]; NumberOfBuffers = size; next_in = 0; next_out = 0; current_size = 0; } 5/29/2016 COP4610 14 Bounded buffer monitor – cont. void Put( BufferItem item ) { if( current_size == NumberOfBuffers ) wait( NotFull ); buffer[next_in] = item; next_in = (next_in+1) % NumberOfBuffers; if( ++current_size == 1 ) signal( NotEmpty ); } BufferItem Get( void ) { if( current_size == 0 ) wait( NotEmpty ); BufferItem item = buffer[next_out]; next_out = (next_out+1) % NumberOfBuffers; if( --current_size == NumberOfBuffers-1 ) signal( NotFull ); return item; } } 5/29/2016 COP4610 15 Using a bounded buffer monitor BoundedBufferType BoundedBuffer; int main() { // the Producer while( 1 ) { BufferItem item = ProduceItem(); BoundedBuffer.Put( item ); } } int main() { // the Consumer while( 1 ) { BufferItem item = BoundedBuffer.Get(); ConsumeItem( item ); } } 5/29/2016 COP4610 16 Readers-writers through monitor 5/29/2016 COP4610 17 Example: Readers & Writers monitor readerWriter_1 { startWrite() { int numberOfReaders = 0; numberOfWriters++; int numberOfWriters = 0; while( boolean busy = FALSE; busy || public: (numberOfReaders > 0) startRead() { ) ; while(numberOfWriters != 0); busy = TRUE; numberOfReaders++; }; }; finishWrite() { finishRead() { numberOfWriters--; numberOfReaders-; busy = FALSE; }; }; }; 5/29/2016 COP4610 18 Example: Readers & Writers •Deadlock can happen monitor readerWriter_1 { int numberOfReaders = 0; int numberOfWriters = 0; boolean busy = FALSE; public: startRead() { while(numberOfWriters != 0); numberOfReaders++; }; finishRead() { numberOfReaders--; }; startWrite() { numberOfWriters++; while( busy || (numberOfReaders > 0) ) ; busy = TRUE; }; finishWrite() { numberOfWriters--; busy = FALSE; }; }; 5/29/2016 COP4610 19 Readers-writers through monitor – cont. 5/29/2016 COP4610 20 Readers-writers through monitor – cont. 5/29/2016 COP4610 21 Traffic Synchronization • One-way tunnel • Can only use tunnel if no oncoming traffic • OK to use tunnel if traffic is already flowing the right way 5/29/2016 COP4610 22 Traffic Synchronization 5/29/2016 COP4610 23 Dining-philosopher Monitor 5/29/2016 COP4610 24 Dining-philosopher Monitor – cont. 5/29/2016 COP4610 25 Thread Synchronization in Java • Synchronized – Only one synchronized method for a particular object can be called – Each object contains a monitor, which is automatically part of an object 5/29/2016 COP4610 26 Inter-Process Communication • Inter-Process Communication (IPC) – Allow running processes to communicate with each other • IPC – special cases – Parent and child • Parent passes arguments to child • Parent collect returned status from child using wait – Processes with common ancestors • pipe 5/29/2016 COP4610 27 Inter Process Communication – cont. 5/29/2016 COP4610 28 Inter-Process Communication – cont. • Three styles of inter-process communication – Communication through messages – Through named pipes (using mknod system call) • Like reading and writing files – Through shared memory • Among threads • Among processes • Remote procedure call (RPC) – Between client and server 5/29/2016 COP4610 29 Using Messages to Share Information 5/29/2016 COP4610 30 Communication through Messages • Messages and message queues: – The most common method – Send messages to message queues – Receive messages from message queues • Message system – processes communicate with each other without resorting to shared variables 5/29/2016 COP4610 31 Message Queues • The operating system buffers incoming messages in a mailbox 5/29/2016 COP4610 32 Message Queues – cont. 5/29/2016 COP4610 33 Communication through Messages – cont. • IPC facility provides two operations: – send(message) – message size fixed or variable – receive(message) • If P and Q wish to communicate, they need to – establish a communication link between them – exchange messages via send/receive 5/29/2016 COP4610 34 Send and receive actions 5/29/2016 COP4610 35 Message Related System Calls in UNIX • msgget – Get a message queue • msgsnd – Message send operation • msgrcv – Message receive operation • msgctl – Message control operations 5/29/2016 COP4610 36 Example of message passing paths 5/29/2016 COP4610 37 Mutual exclusion pattern 5/29/2016 COP4610 38 Two-process mutual exclusion • // Convenience procedure void WaitForEmptyMsg( int msg_queue ) { int msg[MsgSize]; ReceiveMessage( msg_queue, msg ); } void main(int argc,char * argv[]) { //Process A or B int mutex_queue = AttachMessageQueue("/usr/queue/FMutex"); // Start with one message in the queue (the ticket) if( IAmProcessA() ) SendMsgTo( mutex_queue ); while( 1 ) { DoOtherThings(); // Not using file F // Enter critical section by getting message WaitForEmptyMsg( mutex_queue ); UseFileF(); SendMsgTo( mutex_queue ); // Leave critical section by returning message } } 5/29/2016 COP4610 39 Mutual exclusion issues • • • • Similar to a solution based on semaphores The solution is simple The solution generalizes to N processes Processes must follow the protocol 5/29/2016 COP4610 40 Process signaling 5/29/2016 COP4610 41 Two-process rendezvous 5/29/2016 COP4610 42 Two-process rendezvous • void main( int argc, char *argv[ ] ) { // Game Player A int b_queue = AttachMessageQueue("/usr/queue/gpb"); SendMsgTo( b_queue, ReadyToStart ); int a_queue = AttachMessageQueue("/usr/queue/gpa"); WaitForEmptyMsg( a_queue ); } void main( int argc, char *argv[ ] ) { // Game Player B int a_queue = AttachMessageQueue("/usr/queue/gpa"); SendMsgTo( a_queue, ReadyToStart ); int b_queue = AttachMessageQueue("/usr/queue/gpb"); WaitForEmptyMsg( b_queue ); } 5/29/2016 COP4610 43 Many-process rendezvous • void main(int argc, char *argv[ ]) { // Coordinator int msg[MsgSize]; int player[NumberOfPlayers], coordinator_queue = AttachMessageQueue( "/usr/queue/coordq" ); for( i = 0; i < NumberOfPlayers; ++i ) { ReceiveMessage( coordinator_queue, msg ); player[i] = msg[1]; } for( i = 0; i < NumberOfPlayers; ++i ) SendMsgTo( player[i], BeginPlaying ); } void main( int argc, char *argv[ ] ) { // Player I int coordinator_queue = AttachMessageQueue( "/usr/queue/coordq" ); char qname[32]; sprintf( qname, "/usr/queue/%s", argv[1] ); int my_queue = AttachMessageQueue( qname ); SendMsgTo(coordinator_queue,ReadyToStart,my_queue); WaitForEmptyMsg( my_queue ); } 5/29/2016 COP4610 44 Three-process rendezvous 5/29/2016 COP4610 45 Events • Events can be used to coordinate processes – An event represents the occurrence of some condition – A process can synchronize with an event by blocking itself until the event occurs – When the event occurs, the OS informs the blocked process of the occurrence 5/29/2016 COP4610 46 UNIX Signal • A signal in UNIX is a mechanism by which the OS can inform a process of the occurrence of some event – A signal can be raised by one process using kill system call, thus causing another process to be interrupted and to optionally catch the signal – Signals can also be used among user processes 5/29/2016 COP4610 47 UNIX Signal – cont. 5/29/2016 COP4610 48 UNIX Signal – cont. 5/29/2016 COP4610 49 Remote Procedure Call • RPC is designed to hide all the details from programmers – Overcome the difficulties with message-passing model • It extends the conventional local procedure calls to calling procedures on remote computers 5/29/2016 COP4610 50 Conventional Procedure Call a) b) Parameter passing in a local procedure call: the stack before the call to read The stack while the called procedure is active 5/29/2016 COP4610 51 Client and Server Stubs • Principle of RPC between a client and server program. 5/29/2016 COP4610 52 Remote Procedure Calls 5/29/2016 COP4610 53 Remote Procedure Calls – cont. 5/29/2016 COP4610 54 Summary • Monitors are an abstract data type – Can be used to share data safely • Inter-process communications – Through mailboxes – Through messages – Through signals (especially in UNIX) 5/29/2016 COP4610 55