0% found this document useful (0 votes)
6 views51 pages

Synchronization

The document covers synchronization in operating systems, focusing on concurrent programming, Java synchronization mechanisms, and classical synchronization problems like the Producer/Consumer and Readers/Writers problems. It explains concepts such as semaphores, critical sections, and mutual exclusion, as well as Java's built-in synchronization features like synchronized methods and wait/notify mechanisms. Additionally, it discusses issues like deadlock and starvation in the context of process synchronization.

Uploaded by

hamid
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views51 pages

Synchronization

The document covers synchronization in operating systems, focusing on concurrent programming, Java synchronization mechanisms, and classical synchronization problems like the Producer/Consumer and Readers/Writers problems. It explains concepts such as semaphores, critical sections, and mutual exclusion, as well as Java's built-in synchronization features like synchronized methods and wait/notify mechanisms. Additionally, it discusses issues like deadlock and starvation in the context of process synchronization.

Uploaded by

hamid
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

CMPS 405: OPERATING SYSTEMS

Synchronization

This material is based on the operating system books by Silberschatz and Stallings
and other Linux and system programming books.
Operating Systems, CSE Dept., Qatar University
Objectives
 Motivations
 Concurrent Programming
 Producer/Consumer Problem
 Synchronization Terminology
 Cooperative Processes Interaction Structure

 Java Synchronization
 Java Object locking (Synchronized Access)
 Using yield,
 Using wait/notify and wait/notifyAll methods pairs

 Synchronization with Semaphores


 The Concept of a Semaphore

Operating Systems, CSE Dept., Qatar University


Objectives
 Java API Support for Concurrency
 java.util.concurrent
 Semaphores in java.util.concurrent.Semaphore
 Reentrant Locks in java.util.concurrent.locks.ReentrantLock

 Classical Synchronization Problems


 Producer/Consumer Problem
 Readers/Writers Problem

Operating Systems, CSE Dept., Qatar University


Concurrent Programming
 In sequential programming: all computational tasks are executed in
sequence, one after the other.

 In concurrent programming: multiple computational tasks are executed


simultaneously, at the same time.

 Implementation of concurrent tasks:


 as separate programs
 as a set of processes or threads created by a single program

 Execution of concurrent tasks:


 on a single processor
 Multithreaded programming
 on several processors in close proximity
 Parallel computing
 on several processors distributed across a network
 Distributed computing

Operating Systems, CSE Dept., Qatar University


Producer/Consumer Problem
 Paradigm for cooperating
processes, producer process Producer
produces information that is
consumed by a consumer insert(item)

process.
 unbounded-buffer places no Buffer
practical limit on the size of
the buffer.
remove()
 bounded-buffer assumes that
there is a fixed buffer size. Consumer

Operating Systems, CSE Dept., Qatar University


Modeling The Shared Buffer
Buffer<interface>
void insert(Object)
Object remove()

BoundedBuffer<class> UnBoundedBuffer<class>

Operating Systems, CSE Dept., Qatar University


Bounded Buffer Implementation
public class BoundedBuffer implements Buffer {
count
private static final int BUFFER_SIZE = 5;
private int count; out in 3
private int in;
private int out; X X X
private Object[] buffer;
public BoundedBuffer(){ }
public void insert(Object item){ } public BoundedBuffer() {
public Object remove(){ } count = 0; in = 0; out = 0;
} buffer = new Object[BUFFER_SIZE];
}

public void insert(Object item) { public Object remove() {


while (count == BUFFER_SIZE); Object item;
++count; while (count == 0);
buffer[in] = item; --count;
in = (in + 1) % BUFFER_SIZE; item = buffer[out];
} out = (out + 1) % BUFFER_SIZE;
return item;
}
Operating Systems, CSE Dept., Qatar University
The Producer
import java.util.*;
public class Producer implements Runnable {
private Buffer buffer;

public Producer(Buffer b) {
buffer = b;
}

public void run() {


Date message;
while (true) {
int sleeptime = (int) (5000 * Math.random());
System.out.println("Producer napping "+sleeptime+" milliseconds");
try {Thread.sleep(sleeptime); }
catch (InterruptedException e){ }
message = new Date();
System.out.println("Producer is a wake and produced " + message);
buffer.insert(message);
}
}

}
Operating Systems, CSE Dept., Qatar University
The Consumer
import java.util.*;
public class Consumer implements Runnable {
private Buffer buffer;

public Consumer(Buffer b) {
buffer = b;
}

public void run() {


Date message;
while (true) {
int sleeptime = (int) (5000 * Math.random());
System.out.println("Consumer napping "+sleeptime+" milliseconds");
try {sleep(sleeptime);}
catch (InterruptedException e){}
System.out.println("Consumer is awake and wants to consume.");
message = (Date) buffer.remove();
System.out.println(“Consumer is a wake and consumed " + message);
}
}

}
Operating Systems, CSE Dept., Qatar University
The Factory Class

public class Factory{

public Factory(){
Buffer buffer = new BoundedBuffer();
Thread producerThread = new Thread(new Producer(buffer));
Thread consumerThread = new Thread(new Consumer(buffer));

producerThread.start();
consumerThread.start();
}

public static void main(String args[]) {


new Factory();
}

Operating Systems, CSE Dept., Qatar University


The Problem
 Concurrent access to shared data may result in data
inconsistency

 Maintaining data consistency requires mechanisms


to ensure the orderly execution of cooperating
processes

 We can do so by having an integer count that keeps


track of the number of full buffers. Initially, count is
set to 0. It is incremented by the producer after it
produces a new buffer and is decremented by the
consumer after it consumes a buffer.
Operating Systems, CSE Dept., Qatar University
Threads accessing shared data

Body of the insert method


invoked by the Producer

Body of the remove


method invoked
by the Consumer

Operating Systems, CSE Dept., Qatar University


Synchronization Terminology
 Concurrent accesses to same shared variable, where at least one access is
a write, would result in:
 Incorrect results following order of accesses
 Irregular errors, very hard to debug

 Definition of Race Condition: the situation when there is concurrent


access to shared data and the final outcome depends upon order of
execution.

 Definition of Critical Section: Section of code where shared data is


accessed.

 Definition of Synchronization: Mechanism that allows the programmer to


control the relative order in which operations occur in different threads or
processes. (Coordinate Access of shared data)

 Definition of Mutual Exclusion - If process Pi is executing in its critical


section, then no other processes can be executing in their critical sections.

Operating Systems, CSE Dept., Qatar University


Cooperative Processes Interaction Structure

....

Process/thread 1 ....... Process/thread n

 Entry Section - Code that requests permission to enter its critical section.
 Exit Section - Code that runs after exiting the critical section

Operating Systems, CSE Dept., Qatar University


Java Synchronization
 Java provides synchronization at the language-level.

 Each Java object has an associated lock.


 This lock is acquired by invoking a synchronized method.
 This lock is released when exiting the synchronized method.

 Threads waiting to acquire the object lock are placed in the entry set for the
object lock.

Each object has an associated entry set.

Operating Systems, CSE Dept., Qatar University


Synchronized Objects in Java
 Apply synchronized keyword to object
 Mutual exclusion for code in synchronization block
 Example:

Object x = new Object();


synchronized(x) { // acquire lock on x on entry
... // hold lock on x in block
} // release lock on x on exit

Operating Systems, CSE Dept., Qatar University


Synchronized Methods in Java
 Java methods also provide locks:
 Apply synchronized keyword to method
 Mutual exclusion for entire body of method
 Synchronizes on object invoking method
 Example:
synchronized foo() { …code… }
shorthand notation for

foo() {
synchronized (this) { …code… }
}

Operating Systems, CSE Dept., Qatar University


Synchronized Methods in Java

Public synchronized void insert(Object item){

…… // body of the method goes here

Short hand notation for

Public void insert(Object item){


synchronized(this){

…… // body of the method goes here

}
}
Operating Systems, CSE Dept., Qatar University
Locks in Java
 Properties:
 No other thread can get lock on x while in block
 Locked block of code critical section

 Lock is released when block terminates:


 End of block reached
 Exit block due to return, continue, break
 Exception thrown

Operating Systems, CSE Dept., Qatar University


Java Synchronization: Remarks
 Use same lock to provide mutual exclusion

 Ensure atomic transactions:


 Sequence of actions must be performed as single
 Ensure lock is held for duration of transaction
 atomic transaction to avoid data race ONLY.

 Avoiding deadlock
 Potential problem:
 Threads holding lock may be unable to obtain lock held by other
thread, and vice versa
 Thread holding lock may be waiting for action performed by
other thread waiting for lock
 Program is unable to continue execution (deadlock)

Operating Systems, CSE Dept., Qatar University


Example: Producer/Consumer Problem
Synchronized insert() and remove() methods

Operating Systems, CSE Dept., Qatar University


Java Synchronization wait/notify()
 When a thread invokes wait():
1. The thread releases the object lock;
2. The state of the thread is set to Blocked;
3. The thread is placed in the wait set for the object.

 When a thread invokes notify():


1. An arbitrary thread T from the wait set is selected;
2. T is moved from the wait to the entry set;
3. The state of T is set to Runnable.

 When a thread invokes notifyAll():


 selects all threads in the wait set and moves them to the entry set.

Entry and wait sets


Operating Systems, CSE Dept., Qatar University
Java Synchronization wait/notify()
 Synchronization rules in Java:
 A thread that owns the lock for an object can enter another synchronized
method (or block) for the same block. This is known recursive lock.

 A thread can nest synchronized method invocations for different objects.


Thus, a thread can simultaneously own the lock of several different
objects.

 If a method is not declared synchronized, then it can be invoked


regardless of lock ownership, even when another synchronized method
for the same object is executing.

 If the wait set of an object is empty, then the call for notify() or
notifyall() has no effect.

 wait(), notify(), and notifyall() may only be invoked from synchronized


methods or blocks; otherwise, an IllegalMonitorStateException is
thrown.

Operating Systems, CSE Dept., Qatar University


Java Thread States

Operating Systems, CSE Dept., Qatar University


Producer/Consumer Problem

Operating Systems, CSE Dept., Qatar University


Readers/Writers Problem
A data set S is shared among a number of
concurrent processes
 Readers – only read the data set; they do not perform any
updates
 Writers – can both read and write.
 In other words:
o Any number of readers can access S at the same time.
o No writer can access S at the same time as a reader or another
writer.

 OS examples: file locks

Operating Systems, CSE Dept., Qatar University


Readers-Writers Problem
Interface for read-write locks

Operating Systems, CSE Dept., Qatar University


Java Synchronization - Readers-Writers

Operating Systems, CSE Dept., Qatar University


Java Synchronization - Readers-Writers
Methods called by readers

Operating Systems, CSE Dept., Qatar University


Java Synchronization - Readers-Writers
Methods called by writers

Operating Systems, CSE Dept., Qatar University


The Concept of a Semaphore
 A Semaphore is a synchronization tool that does not require busy waiting
 Semaphore S – integer variable
 Two standard operations modify S: In Dutch proberen
 acquire() and release() (test)
 Originally called P() and V() In Dutch verhogen
 Less complicated (increment)
 Can only be accessed via two indivisible (atomic) operations

Operating Systems, CSE Dept., Qatar University


Semaphore as General Synchronization Tool
 Counting semaphore – integer value can range over an
unrestricted domain
 Binary semaphore – integer value can range only between 0
and 1; can be simpler to implement
 Also known as mutex locks

Usage of Semaphores

Operating Systems, CSE Dept., Qatar University


Semaphore Implementation
Busy wait: while a process is in its
critical section, any other process
trying to enter its critical section
must loop continuously in the entry
code.

Spin Lock: is a semaphore with


busy wait, process spins while
Waiting for the lock.

In a single CPU multiprogramming System where locks are expected to be held


for long time – critical section is long -, busy wait wastes CPU cycles that some
other process might be able to use productively.

In a multiprocessor System where locks are expected to be held for short time –
critical section is short -, busy wait is useful requiring no context switching.

But in most applications, locks are expected to be held for long time – critical
section is long – So, this implementation is not good.

Operating Systems, CSE Dept., Qatar University


Semaphore Implementation with no Busy waiting

 With each semaphore there is an associated waiting queue.


Each entry in a waiting queue has two data items:
 value (of type integer)
 pointer to next record in the list

 Two operations:
 block – place the process invoking the operation on the
appropriate waiting queue.
 wakeup – remove one of processes in the waiting queue
and place it in the ready queue.

Operating Systems, CSE Dept., Qatar University


Semaphore Implementation with no Busy waiting (Cont.)

 Number of available resources, value ≥ 0


meaning (Value) = 
| value | is the number of waiting processes, value ≤ 0

Operating Systems by Mohammad Saleh, CSE Dept., Qatar University


Deadlock and Starvation
 Deadlock – two or more processes are waiting indefinitely for an event that
can be caused by only one of the waiting processes

 Let S and Q be two semaphores initialized to 1.

P0 P1
Waits for Waits for
S.acquire(); Q.acquire(); P0 to
P1 to
release Q. Q.acquire(); S.acquire(); release S.
. .
. .
. .
S.release(); Q.release();
Q.release(); S.release();

 Starvation – indefinite blocking. A process may never be removed from the


semaphore queue in which it is suspended.
Operating Systems, CSE Dept., Qatar University
The Producer/Consumer Problem

•Semaphore mutex
initialized to the value 1
•Semaphore full
initialized to the value 0.
•Semaphore empty
initialized to the value N.

Operating Systems, CSE Dept., Qatar University


The Producer/Consumer Problem

Operating Systems, CSE Dept., Qatar University


The Producer/Consumer Problem

Operating Systems, CSE Dept., Qatar University


The Producer/Consumer Problem

Operating Systems, CSE Dept., Qatar University


The Producer/Consumer Problem

Operating Systems, CSE Dept., Qatar University


The Readers/Writers Problem
 Shared Data
 Data set
 Semaphore mutex initialized to 1.
 Semaphore db initialized to 1.
 Integer readerCount initialized to 0.

Operating Systems, CSE Dept., Qatar University


The Readers/Writers Problem
public class Database implements RWLock {

// the number of active readers


private int readerCount;

Semaphore mutex; // controls access to readerCount


Semaphore db; // controls access to the database

public Database() {
readerCount = 0;
mutex = new Semaphore(1);
db = new Semaphore(1);
}

Operating Systems, CSE Dept., Qatar University


The Readers/Writers Problem
Methods called by readers
public void acquireReadLock(int readerNum) {
mutex.acquire();
++readerCount;

// if I am the first reader tell all others


// that the database is being read
if (readerCount == 1)
db.acquire();
System.out.println("Reader " + readerNum
+ " is reading. Reader count = " + readerCount);
mutex.release();
}

public void releaseReadLock(int readerNum) {


mutex.acquire();
--readerCount;
// if I am the last reader tell all others
// that the database is no longer being read
if (readerCount == 0)
db.release();
System.out.println("Reader " + readerNum
+ " is done reading. Reader count = " + readerCount);
mutex.release();
}
Operating Systems, CSE Dept., Qatar University
The Readers/Writers Problem
Methods called by writers

public void acquireWriteLock(int writerNum) {

db.acquire();
System.out.println("writer " + writerNum + " is
writing.");

public void releaseWriteLock(int writerNum) {

System.out.println("writer " + writerNum + " is done


writing.");
db.release();
}

} //ends class DataBase

Operating Systems, CSE Dept., Qatar University


The Readers/Writers Problem

Operating Systems, CSE Dept., Qatar University


The Readers/Writers Problem

Operating Systems, CSE Dept., Qatar University


Java Concurrency: Semaphore
 Java has a package specifically to support concurrency
programming.

 The package is java.util.concurrent

 It has supported solutions for Semaphore synchronization


 Semaphores in java.util.concurrent.Semaphore

Operating Systems, CSE Dept., Qatar University


Java Semaphores
 To create a semaphore call the constructor
 Semaphore(int value)

 To acquire a permit from this semaphore, blocking until one is available, or


the thread is interrupted
 void acquire()

 To acquire the given number of permits from this semaphore, blocking


until all are available, or the thread is interrupted
 void acquire(int permits)

 To return the current number of permits available in this semaphore


 int availablePermits()

 To release a permit, returning it to the semaphore


 void release()

 To release the given number of permits, returning them to the semaphore


 void release(int permits)
Operating Systems, CSE Dept., Qatar University
Java Semaphores
 How to?
 import java.util.concurrent.Semaphore;
 Usage:
Semaphore sem = new Semaphore(1);
//……….
try{
sem.acquire();
//critical section
}
finally{
sem.release();
}

Operating Systems, CSE Dept., Qatar University


Java Reentrant Locks
 Java API ReentrantLock is owned by a single thread and is used to provide
a mutually exclusive access to a shared resource.

 One additional feature of ReentrantLock is setting fairness parameter,


which favors granting the lock to the longest-waiting thread.

 How to?
 import java.util.concurrent.locks.ReentrantLock;
 Usage:
lock key = new ReentrantLock();
key.lock();
try{
//critical section
}
finally{
key.unlock();
}

Operating Systems, CSE Dept., Qatar University

You might also like