Steve’s Concurrency Slides

Slides:



Advertisements
Similar presentations
1 Chapter 5 Concurrency: Mutual Exclusion and Synchronization Principals of Concurrency Mutual Exclusion: Hardware Support Semaphores Readers/Writers Problem.
Advertisements

Concurrency: Mutual Exclusion and Synchronization Chapter 5.
Operating Systems: A Modern Perspective, Chapter 8 Slide 8-1 Copyright © 2004 Pearson Education, Inc.
Chapter 6: Process Synchronization
5.1 Silberschatz, Galvin and Gagne ©2009 Operating System Concepts with Java – 8 th Edition Chapter 5: CPU Scheduling.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
Process Synchronization. Module 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores.
CH7 discussion-review Mahmoud Alhabbash. Q1 What is a Race Condition? How could we prevent that? – Race condition is the situation where several processes.
Operating Systems CMPSC 473 Mutual Exclusion Lecture 13: October 12, 2010 Instructor: Bhuvan Urgaonkar.
Concurrency in Shared Memory Systems Synchronization and Mutual Exclusion.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han.
Chapter 6: Process Synchronization. Outline Background Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores Classic Problems.
Slide 8-1 Copyright © 2004 Pearson Education, Inc. Basic Synchronization Principles.
Basic Synchronization Principles. Concurrency Value of concurrency – speed & economics But few widely-accepted concurrent programming languages (Java.
1 Chapter 6: Concurrency: Mutual Exclusion and Synchronization Operating System Spring 2007 Chapter 6 of textbook.
© 2004, D. J. Foreman 1 Mutual Exclusion © 2004, D. J. Foreman 2  Mutual exclusion ■ Critical sections ■ Primitives  Implementing it  Dekker's alg.
Instructor: Umar KalimNUST Institute of Information Technology Operating Systems Process Synchronization.
Adopted from and based on Textbook: Operating System Concepts – 8th Edition, by Silberschatz, Galvin and Gagne Updated and Modified by Dr. Abdullah Basuhail,
Operating Systems CSE 411 CPU Management Oct Lecture 13 Instructor: Bhuvan Urgaonkar.
Concurrency, Mutual Exclusion and Synchronization.
Critical Problem Revisit. Critical Sections Mutual exclusion Only one process can be in the critical section at a time Without mutual exclusion, results.
Operating Systems: A Modern Perspective, Chapter 8 Slide 8-1 Copyright © 2004 Pearson Education, Inc.
CSC321 Concurrent Programming: §5 Monitors 1 Section 5 Monitors.
Silberschatz, Galvin and Gagne  Operating System Concepts Chapter 7: Process Synchronization Background The Critical-Section Problem Synchronization.
Concurrency: Mutual Exclusion and Synchronization Chapter 5.
1 Outline for Today Objective: –5 Dining Philosophers –Reader-writer problem –Message Passing Administrative details: –Check for demo location with grader.
Chapter 6: Process Synchronization. 6.2 Silberschatz, Galvin and Gagne ©2005 Operating System Concepts Module 6: Process Synchronization Background The.
Operating Systems CSE 411 CPU Management Dec Lecture Instructor: Bhuvan Urgaonkar.
Concurrency in Shared Memory Systems Synchronization and Mutual Exclusion.
1.  Independent process  Cannot affect or be affected by the other processes in the system  Does not share any data with other processes  Interacting.
Operating Systems: A Modern Perspective, Chapter 8 Slide 8-1 Copyright © 2004 Pearson Education, Inc.
Operating Systems: A Modern Perspective, Chapter 8 Slide 8-1 Copyright © 2004 Pearson Education, Inc.
Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han.
CS4315A. Berrached:CMS:UHD1 Process Synchronization Chapter 8.
Process Synchronization CS 360. Slide 2 CS 360, WSU Vancouver Process Synchronization Background The Critical-Section Problem Synchronization Hardware.
Process Synchronization. Objectives To introduce the critical-section problem, whose solutions can be used to ensure the consistency of shared data To.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Chapter 6: Process Synchronization.
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts – 9 th Edition Chapter 5: Process Synchronization.
Chapter 6 Synchronization Dr. Yingwu Zhu. The Problem with Concurrent Execution Concurrent processes (& threads) often access shared data and resources.
Basic Synchronization Principles 1. 2  Independent process  Cannot affect or be affected by the other processes in the system  Does not share any.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization Operating Systems: Internals and Design Principles, 6/E William Stallings Patricia Roy Manatee.
Process Synchronization
Concurrency: Mutual Exclusion and Synchronization
Process Synchronization: Semaphores
Background on the need for Synchronization
More on Classic Synchronization Problems, Monitors, and Deadlock
Chapter 5: Process Synchronization
Basic Synchronization Principles
143a discussion session week 3
Basic Synchronization Principles
Concurrency: Mutual Exclusion and Synchronization
Semaphore Originally called P() and V() wait (S) { while S <= 0
Process Synchronization
Module 7a: Classic Synchronization
Lecture 2 Part 2 Process Synchronization
Concurrency: Mutual Exclusion and Process Synchronization
Chapter 6: Process Synchronization
Chapter 6 Synchronization Principles
CSE 451: Operating Systems Autumn 2003 Lecture 7 Synchronization
CSE 451: Operating Systems Autumn 2005 Lecture 7 Synchronization
CSE 451: Operating Systems Winter 2003 Lecture 7 Synchronization
CSE 153 Design of Operating Systems Winter 19
CSE 153 Design of Operating Systems Winter 2019
Outline Announcements Basic Synchronization Principles – continued
Chapter 6: Synchronization Tools
Outline Please turn in Homework #2 Announcements
Steve’s Concurrency Slides
Process/Thread Synchronization (Part 2)
CSE 542: Operating Systems
Presentation transcript:

Steve’s Concurrency Slides

What is Synchronization? Ability of Two or More Serial Processes to Interact During Their Execution to Achieve Common Goal Recognition that “Today’s” Applications Require Multiple Interacting Processes Client/Server and Multi-Tiered Architectures Inter-Process Communication via TCP/IP Fundamental Concern: Address Concurrency Control Access to Shared Information Historically Supported in Database Systems Currently Available in Many Programming Languages

Thread Synchronization Suppose X and Y are Concurrently Executing in Same Address Space What are Possibilities? What Does Behavior at Left Represent? Synchronous Execution! X Does First Part of Task Y Next Part Depends on X X Third Part Depends on Y Threads Must Coordinate Execution of Their Effort X Y 1 2 3

Thread Synchronization Now, What Does Behavior at Left Represent? Asynchronous Execution! X Does First Part of Task Y Does Second Part Concurrent with … X Doing Third Part What are Issues? X Y 1 2 3 Will Second Part Still Finish After Third Part? Will Second Part Now Finish Before Third Part? What Happens if Variables are Shared?

What are Potential Problems without Synchronization? Data Inconsistency Lost-Update Problem Impact on Correctness of Executing Software Deadlock Two Processes Each Hold Unique Resource and Want Resource of Other Process Processes Wait Forever Non-Determinacy of Computations Behavior of Computation Different for Different Executions Two Process Produce Different Results When Executed More than Once on Same Data

What are Classic Synchronization Techniques? Goal: Shared Variables and Resources Two Approaches: Critical Sections Define a Segment of Code as Critical Section Once Execution Enters Code Segment it Cannot be Interrupted by Scheduler Release Point for Critical Section for Interrupts Semaphores Proposed in 1960s by E. Dijkstra Utilizes ADTs to Design and Implement Behavior that Guarantees Consistency and Non-Deadlock

Critical Sections Two Processes Share “balance” Data Item Remember, Assignment is Not Atomic, but May Correspond to Multiple Assembly Instructions What is Potential Problem? shared float balance; Code for p1 Code for p2 . . . . . . balance = balance + amount; balance = balance - amount; p1 p2 balance

Critical Sections Recall the Code Below What Happens if Time Slice Expires at Arrow and an Interrupt is Generated? shared double balance; Code for p1 Code for p2 . . . . . . balance = balance + amount; balance = balance - amount; Code for p1 Code for p2 load R1, balance load R1, balance load R2, amount load R2, amount add R1, R2 sub R1, R2 store R1, balance store R1, balance

Critical Sections (continued) There is a Race to Execute Critical Sections Sections May Be Different Code in Different Processes: Cannot Detect With Static Analysis Results of Multiple Execution Are Not Determinate Need an OS Mechanism to Resolve Races If p1 Wins, R1 and R2 Added to Balance - Okay If p2 Wins, its Changed Balance Different from One Held by p1 which Adds/Writes Wrong Value Code for p1 Code for p2 load R1, balance load R1, balance load R2, amount load R2, amount add R1, R2 sub R1, R2 store R1, balance store R1, balance

One Solution: Disabling Interrupts In Code Below, Disable Interrupts What are Potential Problems? Interrupts Could Be Disabled Arbitrarily Long Were Trusting Software Engineers Unintentional(Infinite Loop) or Malicious Code Concurrent PLs Enforce Primitives at Compile Really Only Want to Prevent P1 and P2 From Interfering With One Another Another Solution: Using Shared “Lock” Variable shared double balance; Code for p1 Code for p2 disableInterrupts(); disableInterrupts(); balance = balance + amount; balance = balance - amount; enableInterrupts(); enableInterrupts();

Using a Lock Variable Shared lock Flag Initialized to False First Process to be Active Sets lock to TRUE Enter Critical Section Change balance Set lock to FALSE Leave Critical Section Where are Two Trouble Spots? shared boolean lock = FALSE; shared double balance; Code for p1 /* Acquire the lock */ while(lock) ; lock = TRUE; /* Execute critical sect */ balance = balance + amount; /* Release lock */ lock = FALSE; Code for p2 What if Interrupt Occurs Here? What if Interrupt Occurs Here?

Using a Lock Variable p2 p1 shared boolean lock = FALSE; shared double balance; Code for p1 /* Acquire the lock */ while(lock) ; lock = TRUE; /* Execute critical sect */ balance = balance + amount; /* Release lock */ lock = FALSE; Code for p2 /* Acquire the lock */ while(lock) ; lock = TRUE; /* Execute critical sect */ balance = balance + amount; /* Release lock */ lock = FALSE; Blocked at while p2 p1 lock = TRUE Interrupt Interrupt lock = FALSE Interrupt

Lock Manipulation Consider the Following enter/exit Primitives that Will be Utilized to Insure No Interrupts During How Does Code Below Insure that Interrupts are Disabled? enter(lock) { exit(lock) { disableInterrupts(); disableInterrupts(); /* Loop until lock is TRUE */ lock = FALSE; while(lock) { enableInterrupts(); /* Let interrupts occur */ } enableInterrupts(); disableInterrupts(); } lock = TRUE; What Occurs Here? Remember, Need Location for Interrupts to Occur During Attempt to Acquire Lock!

Utilizing Enter and Exit Example: List Manipulator Add or Delete an Element From a List Adjust the List Descriptor, e.g., Length Modify List Content and Length A Transaction is a List of Operations The System Begins to Execute a Transaction Execution Must Occur on All Operations that Comprise Transaction Without Interruption Or, the Transaction Must Not Execute Any Operations at All Concept of Atomic Transaction

Processing Two Transactions shared boolean lock2 = FALSE;lock1 = FALSE; shared list L; Code for p1 Code for p2 . . . . . . /* Enter CS to delete elt */ /* Enter CS to update len */ enter(lock1); enter(lock2); <delete element>; <update length>; /* Exit CS */ /* Exit CS */ exit(lock1); exit(lock2); <intermediate computation>; <intermediate computation> /* Enter CS to update len */ /* Enter CS to add elt */ enter(lock2); enter(lock1); <update length>; <add element>; exit(lock2); exit(lock1); . . . . . . Notice Any Problems with Code for Processes? Interrupt of p1 After Delete But Before Update If p2 Adds Element and Updates Length, Inconsistency Occurs

Deadlock Why and How Does Deadlock Occur? Code for p1 Code for p2 shared boolean lock1 = FALSE; lock2 = FALSE;shared list L; Code for p1 Code for p2 . . . . . . /* Enter CS to delete elt */ /* Enter CS to upd len */ enter(lock1); enter(lock2); <delete element>; <update length>; <intermediate computation>; <intermediate comp> /* Enter CS to update len */ /* Enter CS to add elt */ enter(lock2); enter(lock1); <update length>; <add element>; /* Exit both CS */ /* Exit both CS */ exit(lock1); exit(lock2); exit(lock2); exit(lock1); . . . . . . Why and How Does Deadlock Occur?

Coordinating Processes Can Synchronize With FORK, JOIN & QUIT Terminate Processes With QUIT to Synchronize Create Processes Whenever Critical Section is Complete See Figure 8.7 Problems with All Approaches so Far Reliance on Software Engineers Error Prone and Difficult to Enforce Alternative is to Create OS Primitives Similar to the enter/exit Primitives

Some Constraints for “Ideal” Synchronization Mechanism Processes will Enter Critical Sections Mutual Exclusion: Only One Process at any One Time in Allowed in the CS Only Processes Competing for a CS are Involved in Resolving Who Enters the CS Once a Process Attempts to Enter its CS, it Cannot be Postponed Indefinitely After Requesting Entry, Only a Bounded Number of Other Processes May Enter Before the Requesting Process Latter Two Points Prevent Starvation!

Assumptions About Solutions Memory Read/Writes Are Indivisible Process A Reads X; Process B Writes X Either A Reads X; B Writes X B Writes X; A Reads X Simultaneous Attempts Result in Some Arbitrary Order of Access There is No Priority Among the Processes Relative Speeds of the Processes/Processors is Unknown Processes Are Cyclic and Sequential

Dijkstra Semaphore Classic Paper Describes Several Software Attempts to Solve the Problem (See Exercise 4, Section 8.6) Dijkstra First Found a Software Solution Then Proposed Simpler Hardware-Based Solution What is a Semaphore S? A Nonnegative Integer Variable Can Only Be Changed or Tested by Two Indivisible Functions: For V(s), No Interrupt is Possible For P(s), Interrupt During {wait}; Only V(s): [s = s + 1] P(s): [while(s == 0){wait}; s = s - 1]

How Do P & V Work? What is the Initial Value of Binary Semaphore? Initial Value Set as Part of Shared Variable semaphore mutex = 1; Followed by Spawning of Two or More Processes What Does it Mean When mutex = 0? Process X Executed P(mutex) with mutex = 1 What About Other Processes Trying P(mutex)? Others Wait Until Process X Does V(mutex) If X is Interrupt Before V, Others Still Wait V(mutex): [mutex = mutex + 1] P(mutex): [while(mutex == 0){wait}; mutex = mutex - 1]

Using Semaphores to Solve the Canonical Problem proc_0() { proc_1() { while(TRUE) { while(TRUE { <compute section>; <compute section>; P(mutex); P(mutex); <critical section>; <critical section>; V(mutex); V(mutex); } } } } semaphore mutex = 1; // Shared variable fork(proc_0, 0); fork(proc_1, 0); What if First P(mutex); Called by proc_0? s = 1 while false so s = 0 What if Interrupt Occurs in CS of proc_0? proc_1() Waits Until proc_0 Resumes When CS Finishes V is Fired to Set s = 1 V(s):[s = s + 1] P(s):[while(s==0) {wait}; s = s - 1]

Shared Account Problem proc_0() { proc_1() { . . . . . . /* Enter the CS */ /* Enter the CS */ P(mutex); P(mutex); balance += amount; balance -= amount; V(mutex); V(mutex); } } semaphore mutex = 1; // Shared variable fork(proc_0, 0); fork(proc_1, 0); Assume Following Values: balance = 200 amount = 50 amount = 75 What are Possible Results? Is there a Lost Update? V(s):[s = s + 1] P(s):[while(s==0) {wait}; s = s - 1]

If proc_0 Interrupted Waits proc_1 balance = 200 amount = 50 amount = 75 V(s):[s = s + 1] P(s):[while(s==0) {wait};s=s-1] proc_0() { proc_1() { . . . . . . /* Enter the CS */ /* Enter the CS */ P(mutex); P(mutex); balance += amount; balance -= amount; V(mutex); V(mutex); } } proc_0 Executes P First If proc_0 Interrupted Waits proc_1 Eventually proc_0 Resumes balance = 250 proc_0 Executes V proc_1 Executes P Sets balance = 175 proc_1 Executes V proc_1 Executes P First If proc_1 Interrupted proc_0 Waits Eventually proc_1 Resumes balance = 125 proc_1 Executes V proc_0 Executes P Sets balance = 175 proc_0 Executes V

Two Shared Variables What is Execution Process That Guarantees proc_A() { while(TRUE) { <compute section A1>; update(x); /* Signal proc_B */ V(s1); <compute section A2>; /* Wait for proc_B */ P(s2); retrieve(y); } semaphore s1 = 0; semaphore s2 = 0; fork(proc_A, 0); fork(proc_B, 0); proc_B() { while(TRUE) { /* Wait for proc_A */ P(s1); retrieve(x); <compute section B1>; update(y); /* Signal proc_A */ V(s2); <compute section B2>; } What is Execution Process That Guarantees x and y are Read After They’re Written?

Execution Process Two Shared Variables integer x,y; semaphore s1=0; semaphore s2=0; proc_A() { while(TRUE) { <compute section A1>; update(x); /* Signal proc_B */ V(s1); <compute section A2>; /* Wait for proc_B */ P(s2); retrieve(y); } P(s1) will not Execute Until V(s1) sets s1 to 1 x Written Before Read proc_B() { while(TRUE) { /* Wait for proc_A */ P(s1); retrieve(x); <compute section B1>; update(y); /* Signal proc_A */ V(s2); <compute section B2>; } P(s2) will not Execute Until V(s2) sets s2 to 1 y Written Before Read Doesn’t Matter if Interrupt Occurs Anywhere Read of Written Data Only After Semaphore Secured

Bounded Buffer Producer/Consumer Model Processes Communicate by Producer Obtains Empty Buffer fr. Pool Producer Fills Buffer & Places in Full Pool Consumer Obtains Info. By Picking Buffer fr. Full Pool Consumer Copies Info Out of Buffer Consumer Places Buffer in Empty Pool N Fixed Number of Buffers Utilize Counting/Binary Semaphores Producer Consumer Empty Pool Full Pool

Bounded Buffer consumer() { producer() { buf_type *next, *here; while(TRUE) { /* Claim full buffer */ P(full); P(mutex); here = obtain(full); V(mutex); copy_buffer(here, next); release(here, emptyPool); /* Signal an empty buffer */ V(empty); consume_item(next); } producer() { buf_type *next, *here; while(TRUE) { produce_item(next); /* Claim an empty */ P(empty); P(mutex); here = obtain(empty); V(mutex); copy_buffer(next, here); release(here, fullPool); /* Signal a full buffer */ V(full); } semaphore mutex = 1; /* A binary semaphore */ semaphore full = 0; /* A general (counting) semaphore */ semaphore empty = N; /* A general (counting) semaphore */ buf_type buffer[N]; fork(producer, 0); fork(consumer, 0);

Execution Process Bounded Buffer semaphore mutex = 1; semaphore full = 0; semaphore empty = N; buf_type buffer[N]; producer() { buf_type *next, *here; while(TRUE) { produce_item(next); /* Claim an empty */ P(empty); P(mutex); here = obtain(empty); V(mutex); copy_buffer(next, here); release(here, fullPool); /* Signal a full buffer */ V(full); } Producers Want Empty Buffers Consumers Want Full Buffers Distinct Empty Buffer Goes to Only 1 Producer consumer() { buf_type *next, *here; while(TRUE) { /* Claim full buffer */ P(full); P(mutex); here = obtain(full); V(mutex); copy_buffer(here, next); release(here, emptyPool); /* Signal an empty buffer */ V(empty); consume_item(next); } Protect Changes to Full Pool Only One Process Accesses Full Pool Full Buffer Now Available Empty Buffer Now Available Protect Changes to Empty Pool

The Readers-Writers Problem Establish Protocol Regarding R/W Access to Shared Resource Writer Excludes Readers (1 W, No R or n R) Write Allows Readers (1W and n R) What is Difference re. Consistency? What is Readers-Writers Problem? Shared Resource (e.g., a File) Readers Share with Other Readers Writer has Exclusive Access What are Potential Problems? When does Write Occur? Can Readers Starve out Writer?

Readers-Writers Problem Shared Resource

Readers-Writers Problem Shared Resource

Readers-Writers Problem Shared Resource

A First Solution First Reader Competes With Writers while(TRUE) { <other computing>; P(mutex); readCount++; if(readCount == 1) P(writeBlock); V(mutex); /* Critical section */ access(resource); readCount--; if(readCount == 0) V(writeBlock); } resourceType *resource; int readCount = 0; semaphore mutex = 1; semaphore writeBlock = 1; fork(reader, 0); fork(writer, 0); writer() { while(TRUE) { <other computing>; P(writeBlock); /* Critical section */ access(resource); V(writeBlock); } First Reader Competes With Writers Last Reader Signals Writers Any Writer Must Wait for All Readers Readers Can Starve Writers “Updates” Can Be Delayed Forever May Not Be What We Want

Writer Takes Precedence reader() { while(TRUE) { <other computing>; P(writePending); P(readBlock); P(mutex1); readCount++; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock); V(writePending); access(resource); readCount--; if(readCount == 0) V(writeBlock); } int readCount=0, writeCount=0; semaphore mutex1= 1, mutex2= 1; semaphore readBlock = 1, writeBlock = 1, writePending = 1; fork(reader, 0); fork(writer, 0); writer() { while(TRUE) { <other computing>; P(mutex2); writeCount++; if(writeCount ==1) P(readBlock); V(mutex2); P(writeBlock); access(resource); V(writeBlock); P(mutex2) writeCount--; if(writeCount == 0) V(readBlock); }

Only Held by One Reader at Time Mutex1 Protects readCount from How Do Different Semaphores Work? semaphore mutex1= 1, mutex2= 1; semaphore readBlock = 1; semaphore writeBlock = 1; semaphore writePending = 1; Only Held by One Reader at Time reader() { while(TRUE) { <other computing>; P(writePending); P(readBlock); P(mutex1); readCount++; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock); V(writePending); access(resource); readCount--; if(readCount == 0) V(writeBlock); } Allow Only One Reader If Writer Waiting Only Reader? Prevent Writer Mutex1 Protects readCount from Multiple Readers Write can Now Proceed Only Reader? Allow Writer

How Do Different Semaphores Work? semaphore mutex1= 1, mutex2= 1; semaphore readBlock = 1; semaphore writeBlock = 1; semaphore writePending = 1; writer() { while(TRUE) { <other computing>; P(mutex2); writeCount++; if(writeCount ==1) P(readBlock); V(mutex2); P(writeBlock); access(resource); V(writeBlock); P(mutex2) writeCount--; if(writeCount == 0) V(readBlock); } Only Writer? Mutex2 Protects writeCount from Multiple Writers Prevent Reader Only Held by One Writer at Time Other Writers and Readers Can Proceed Only Writer? Allow Reader

How Do Different Semaphores Work? semaphore mutex1= 1, mutex2= 1; semaphore readBlock = 1; semaphore writeBlock = 1; semaphore writePending = 1; reader() { while(TRUE) { <other computing>; P(writePending); P(readBlock); P(mutex1); readCount++; if(readCount == 1) P(writeBlock); V(mutex1); V(readBlock); V(writePending); access(resource); readCount--; if(readCount == 0) V(writeBlock); } writer() { while(TRUE) { <other computing>; P(mutex2); writeCount++; if(writeCount ==1) P(readBlock); V(mutex2); P(writeBlock); access(resource); V(writeBlock); P(mutex2) writeCount--; if(writeCount == 0) V(readBlock); }

Monitors Specialized Form of ADT Encapsulates Implementation Public Interface (Types & Functions) Only One Process Can Be Executing (Invoking a Method) in the ADT at a Time One Shared Instance of ADT! monitor anADT { semaphore mutex = 1; // Implicit . . . public: proc_i(…) { P(mutex); // Implicit <processing for proc_i>; V(mutex); // Implicit };

Example: Shared Balance Consider the Shared Balance Monitor Below. Each Method (credit/debit) Define Critical Section Hence, by its Definition … Methods Disable Interrupts at Start of Call and Re-enable Interrupts at End of Call monitor sharedBalance { double balance; public: credit(double amount) {balance += amount;}; debit(double amount) {balance -= amount;}; . . . };

Example: Readers & Writers monitor readerWriter_1 { int numberOfReaders = 0; int numberOfWriters = 0; boolean busy = FALSE; public: startRead() { }; finishRead() { startWrite() { finishWrite() { reader(){ while(TRUE) { . . . startRead(); finishRead(); } fork(reader, 0); fork(reader, 0): fork(writer, 0); writer(){ while(TRUE) { . . . startWrite(); finishWrite(); }

Example: Readers & Writers 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;

Example: Readers & Writers monitor readerWriter_1 { int numberOfReaders = 0; int numberOfWriters = 0; boolean busy = FALSE; public: startRead() { while(numberOfWriters != 0); numberOfReaders++; }; finishRead() { numberOfReaders--; Deadlock can Occur! startWrite() { numberOfWriters++; while( busy || (numberOfReaders > 0) ) ; busy = TRUE; }; finishWrite() { numberOfWriters--; busy = FALSE;

Condition Variables Essentially an Event (As Defined Previously) Global Condition Visible to All Methods Defined in Monitor -- Occurs Only Inside a Monitor Operations to Manipulate Condition Variable Wait: Suspend Invoking Process Until Another Executes a Signal Signal: Resume One Process If Any Are Suspended, Otherwise Do Nothing Queue: Return TRUE If There is at Least One Process Suspended on the Condition Variable Conditions Increase Complexity of Monitor Transcends Traditional Semaphore Capabilities

Second Try at Readers & Writers monitor readerWriter_2 { int numberOfReaders = 0; boolean busy = FALSE; condition okToRead, okToWrite; public: // startRead and finishRead used by Readers startRead() { if(busy || // busy = TRUE implies writer (okToWrite.queue()) okToRead.wait(); numberOfReaders++; okToRead.signal(); }; finishRead() { numberOfReaders--; if(numberOfReaders == 0) okToWrite.signal();

Second Try at Readers & Writers // startWrite and finishWrite Used by Writers startWrite() { if((numberOfReaders != 0) || busy) okToWrite.wait(); busy = TRUE; }; finishWrite() { busy = FALSE; if(okToRead.queue()) okToRead.signal() else okToWrite.signal() Each Method is Atomic! Cannot be Interrupted!

Example: Synchronizing Traffic One-Way Tunnel Can Only Use Tunnel If No Oncoming Traffic OK to Use Tunnel If Traffic is Already Flowing the Right Way Differentiate Between Northbound and Southbound Traffic Reset Light from Red to Green (and Green to Red) to Control Flow

Example: Synchronizing Traffic monitor tunnel { int northbound = 0, southbound = 0; trafficSignal nbSignal = RED, sbSignal = GREEN; condition busy; public: nbArrival() { if(southbound > 0) busy.wait(); northbound++; nbSignal = GREEN; sbSignal = RED; }; sbArrival() { if(northbound > 0) busy.wait(); southbound++; nbSignal = RED; sbSignal = GREEN;

Ex: Synchronizing Traffic (Continued) depart(Direction exit) ( if(exit = NORTH { northbound--; if (northbound == 0) while(busy.queue()) busy.signal(); else if (exit == SOUTH) { southbound--; if(southbound == 0) } // SOUTH if } // NORTH if }; // depart method }; tunnel monitor