Presentation is loading. Please wait.

Presentation is loading. Please wait.

Background Concurrent access to shared data can lead to inconsistencies Maintaining data consistency among cooperating processes is critical What is wrong.

Similar presentations


Presentation on theme: "Background Concurrent access to shared data can lead to inconsistencies Maintaining data consistency among cooperating processes is critical What is wrong."— Presentation transcript:

1 Background Concurrent access to shared data can lead to inconsistencies Maintaining data consistency among cooperating processes is critical What is wrong with the code to the right? Producer Consumer

2 Race Condition A Condition where the outcome depends on execution order count++, count-- do not use one machine instruction register1=count, register1=register1+1, count=register1 register2=count, register2=register2–1, count=register2 Suppose: P= producer, C= consumer, and count = 5 P: register = count // 5 P: register = register + 1 //6 C: register = count //5 C: register = register – 1 //4 P: count = register //6 C: count = register //4 Questions What is the final value for count? What other possibilities? What should be the correct value? Very difficult to test – can’t control when things happen

3 Critical Sections A block of instructions that must be protected from concurrent execution We cannot assume Process execution speed, although we can assume they all execute at some non zero speed Which process executes next Process execution order Race Condition: Concurrent access to shared data where the output depends on the order of execution

4 Critical-Section Solutions
We need a protocol to guarantee the following: 1. Mutual Exclusion – There is a mechanism to limit the number of processes (normally one) that can execute in a critical section at the same time. 2. Progress - If no process is executing in a critical section, some waiting process must be allowed to enter. Bounded Waiting - A waiting process cannot be kept out of a critical section indefinitely. No assumptions can be made regarding process speed or scheduling order

5 Hardware Solutions Hardware atomic instructions test and set swap
increment and test if zero The lab2 Kernel – cli communication mechanism is like a test and set: if ((cmd = cli.atomicRWCmd(null)) != null)

6 Operating System Synchronization
Uniprocessors – Disable interrupts Currently running code would execute without preemption The executing code must be extremely quick Not scalable to multiprocessor systems, where each processor has its own interrupt vector Multiprocessor - atomic hardware instructions Spin locks are used; must be extremely quick Locks that require significant processing use other mechanisms: preemptible semaphores

7 Semaphores Synchronization tool that uses blocks
acquire() { value--; if (value<0) { add P to list block } } release() { value++; if (value <=0) { remove P from list wakeup(P) } } Synchronization tool that uses blocks A Semaphore is an abstract data type Contains an integer variable (starts at 0) Atomic acquire method (P – proberin (Dutch for ‘to test’)) Atomic release method (V – verhogen (Dutch for ‘to increment’) Includes an implied queue

8 Semaphore for General Synchronization
Counting semaphore the integer value allowed to take on values other than 0 or 1 can count available resources Binary semaphore integer value: 0 or 1 (one permit) Also known as mutex locks Note: Both implemented by the same class -- Semaphore java.util.concurrent.Semaphore sem = new Semaphore(n); sem.acquire() // critical section code sem.release()

9 Java Semaphores (Java 1.5)
public class Worker implements Runnable { private Semaphore sem; public Worker(Semaphore sem) { this.sem = sem; } public void run() { while (true) { sem.acquire(); doSomething(); sem.release(); doMore(); } } public class Factory { public static void main(String[] args) { Semaphore sem = new Semaphore(1); Thread[] bees = new Thread[5]; for (int i=0; i<5; i++) bees[i] = new Worker(sem); for (int i=0; i<5; i++) bees[i].start(); } }

10 Blocking strategy It is possible that a thread needs to block while holding a mutex Issue a wait() call to release the mutex Another process must wake up the waiting thread (notify(), notifyAll(), interrupt()). Otherwise the waiting thread will never execute. Good design will minimize the time spent in critical sections

11 Deadlock and Starvation
Deadlock – two or more processes wait for a resource that can never be satisfied. Let S and Q be two semaphores initialized to 1 P P1 S.acquire(); Q.acquire(); Q.acquire(); S.acquire(); // Critical Section // Critical Section S.release(); Q.release(); Q.release(); S.release(); P0 S.ac() then P1 O.ac() then P0 O.ac()-blocks then P1 S.ac()-blocks -- deadlock Starvation: Continual preemption (indefinite blocking) Could happen if the blocking list is LIFO Process priorities prevent a process from exiting a semaphore queue

12 The Bounded Buffer problem Text section 6.6.1
One or more producers add data to a buffer One or more consumers extract produced data from the buffer for service The buffer holds only n data elements (hence a bounded number) Solution with semaphores Three semaphores, mutex(1), full(n), and empty(n) Initialize mutex to 1, full to 0 and empty to n The full semaphore counts up, and the empty semaphore counts down

13 Bounded Buffer Semaphore Solution
public void insert(Object item) { empty.acquire(); mutex.acquire(); buffer[in] = item; in = (in+1)%SIZE; mutex.release(); fill.release(); } public class BoundedBuffer { private static final int SIZE = 5; private Object[] buffer; private int in, out; private Semaphore mutex, empty, fill; public BoundedBuffer() { in = out = 0; buffer = new Object[SIZE]; mutex = new Semaphore(1); empty = new Semaphore(SIZE); fill = new Semaphore(0); } } public Object remove() { fill.acquire(); mutex.acquire(); Object item = buffer[out]; out = (out+1)%SIZE; mutex.release(); empty.release(); return item; } Demonstrates binary and Counting semaphores

14 The Readers-Writers Problem
Data is shared among concurrent processes Readers: only read the data set, without any updates Writers: May both read and write. Problem Multiple readers can read concurrently Only one writer can concurrently access shared data Shared Data Data set -- next slides simplify the lab problem to a single shared string Semaphore mutex initialized to 1. // writer must have Semaphore db initialized to 1 // Acquired by the first reader Integer readerCount initialized to 0 counting upwards. Note: The best solution is to disallow more readers while a writer waits. Otherwise, a writer may starve.

15 Class describing shared data
class DataLock // named Database in the text { private int readers; private Semaphore mutex, db; public DataLock() { readers = 0; mutex = new Semaphore(1); db = new Semaphore(1); } public void acquireRead() // First reader acquired db { mutex.acquire(); if (++readers==1) db.acquire(); mutex.release(); } public void releaseRead() // Last reader released db { mutex.acquire(); if (--readers==0) db.release(); mutex.release(); } public void acquireWrite() {db.acquire();} public void releaseWrite() {db.release();} } How would we disallow more readers after a write request? (add private boolean writerWaiting; // controlled by mutex)

16 Reader / Writer Classes
class Reader extends Thread { private Database db; private Thread parent; // to make syscalls public Reader(Database db, ReaderWriter parent) {this.db = db; this.parent = parent;} public void run() { while(true) { sleep(500);db.acquireRead(); doRead(); db.releaseRead();} } } class Writer extends Thread { private Database db; private Thread parent; public Writer(Database db, ReaderWriter parent){ this.db = db; this.parent = parent;} { while (true) { sleep(500); db.acquireWrite(); doWrite(); db.releaseWrite();} } } Hints for the lab project make an array of Database objects add throws InterruptedException to the methods Randomly choose the sleep length See demos/lab3.zip

17 Monitors A high-level abstraction integrated into the syntax of the language Only one process may be active within the monitor at a time Monitor without condition variables

18 Java Monitors Every object has a single monitor lock
A call to a synchronized method does the following: Lock Available: acquires the lock Lock Not available: thread blocked and added to the entry set Non synchronized methods ignore the lock Lock released when a synchronized method returns The entry queue algorithm varies (normally FCFS)

19 Java Synchronization Inside a synchronized method:
wait(): block the thread, release lock, move thread to the wait set. notify() An arbitrary thread from the wait set moves to the entry set. A thread not waiting for that condition reissues a wait() notifyAll() All threads in the wait set move to the entry set. Threads not waiting for that condition call wait again Notes: notify() & notifyAll() are ignored if the wait() set is empty wait() & notify() are single condition variables per Java monitors Java 1.5 adds additional condition variable support

20 Java Bounded Buffer with Monitors
public class BoundedBuffer { private int count, in, out; private Object buf; public BoundedBuffer(int size) { count = in = out = 0; buf = new Object[size]; } public synchronized void insert(Object item) throws InterruptedException { while (count==buffer.length) wait(); buf[in] = item; in = (in + 1)%buf.length; ++count; notifyAll(); } public synchronized Object remove() { while (count==0) wait(); Object item = buf[out]; out=(out+1)%buf.length; -- count; notifyAll(); return item;} }

21 Java Readers-Writers with Monitors
public class Database { private int readers; private boolean writers; public Database() {readers=0; writers=false; } public synchronized void acquireRead() throws InterruptedException { while (writers) wait(); ++readers; } public synchronized void releaseRead() { if (--readers==0) notifyAll(); } public synchronized void acquireWrite() { while (readers>0||writers) wait(); writers=true;} public synchronized void releaseWrite() { writers=false; notifyAll(); } }

22 Block Synchronization
Synchronization on an object other than the object executing a synchronized method. “Scope” of a lock (not lexical scope) time between acquire and release A synchronized block might have shorter scope than an entire synchronized method How to do it Instantiate a lock object Use the synchronized keyword around a block Use wait() and notify() calls as needed inside the block Example Object lock=new Object(); synchronized(lock) { // somecritical code. lock.wait(); // more criticalcode lock.notifyAll(); } Question: What's wrong with: synchronized(new Object()) {// code here} Reference to the synchronizing object is not stored in a variable, so is lost.


Download ppt "Background Concurrent access to shared data can lead to inconsistencies Maintaining data consistency among cooperating processes is critical What is wrong."

Similar presentations


Ads by Google