0% found this document useful (0 votes)
14 views

Synchronization

The document discusses process synchronization in the context of the CSS430 course, focusing on concepts such as bounded buffers, race conditions, critical sections, and mutual exclusion. It presents various algorithms for achieving mutual exclusion, including semaphore usage and atomic operations like test-and-set and swap. Additionally, it addresses issues like deadlock and starvation, providing examples and code snippets to illustrate the concepts.

Uploaded by

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

Synchronization

The document discusses process synchronization in the context of the CSS430 course, focusing on concepts such as bounded buffers, race conditions, critical sections, and mutual exclusion. It presents various algorithms for achieving mutual exclusion, including semaphore usage and atomic operations like test-and-set and swap. Additionally, it addresses issues like deadlock and starvation, providing examples and code snippets to illustrate the concepts.

Uploaded by

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

CSS430 Process Synchronization

Textbook Ch6

These slides were compiled from the OSC textbook slides (Silberschatz, Galvin,
and Gagne) and the instructor’s class materials.

CSS430 Processes
Synchronization 1
CSS430 Processes
Synchronization 2
Revisiting Bounded Buffer
public void enter( Object item ) {
while ( count == BUFFER_SIZE )
roducer Process
; // buffer is full! Wait till buffer is consumed
or(int i = 0; ; i++ ) {
++count; Dissect it !!
buffer[in] = item; // add an item
BoundedBuffer.enter(new Integer(i));
in = ( in + 1 ) % BUFFER_SIZE;
}

public object remove( ) {


Object item;
while ( count == 0 )
; // buffer is empty! Wait till buffer is filled
-- count; Dissect it !!
item = buffer[out]; // pick up an item
out = ( out + 1 ) % BUFFER_SIZE;
}
Buffer[0] [1] [2] [3] [4]
Consumer Process

for(int i = 0; ; i++ ) {
out in BoundedBuffer.remove();
CSS430 Processes
}
Synchronization 3
Race Condition
++count: Producer: reg1 = mem[count]; {reg1=5}
reg1 = mem[count]; Producer: reg1 = reg1 + 1; {reg1=6}
reg1 = reg1 + 1; Consumer: reg2 = mem[count]; {reg2=5}
mem[count] = reg1; Consumer: reg2 = reg2 – 1; {reg2=4}
-- count: Producer: mem[count] = reg1; {count=6}
reg2 = mem[count]; Consumer: mem[count] = reg2; {count=4
reg2 = reg2 – 1;
mem[count] = reg2;

 The outcome of concurrent thread execution


depends on the particular order in which the
access takes place = race condition.
CSS430 Processes
Synchronization 4
Critical Section
When coming and entering CS
1. Mutual Exclusion. If process Pi is
executing in its critical section(CS), then
no other processes can be executing in
their critical sections. 3. Delta time exists
2. Progress. If no process is executing in
its CS and there exist some processes 2. Pick up a process to enter
that wish to enter their CS, then the
selection of the processes that will
enter the CS next cannot be postponed Critical Section
indefinitely.
3. Bounded Waiting. A bound must 1. only one process
exist on the number of times that other
processes are allowed to enter their CS
after a process has made a request to
enter its CS and before that request is
granted.
When exiting from CS
CSS430 Processes
Synchronization 5
Worker Thread
public class Worker extends Thread {
public Worker(String n, int i, MutualExclusion s) {
name = n; // my name
id = i; // my thread id
shared = s; // a share object including a critical
section
}
public void run() {
while (true) {
shared.enteringCriticalSection(id);
// in critical section code
shared.leavingCriticalSection(id);
// out of critical section code
}
}
private String name;
private int id;
private MutualExclusion shared;
CSS430 Processes
}
Synchronization 6
Mutual Exclusion Class
public abstract class MutualExclusion {
public static void criticalSection() {
// simulate the critical section
}

public static void nonCriticalSection() {


// simulate the non-critical section
}
public abstract void enteringCriticalSection(int t); // guarantee a mutual execution
public abstract void leavingCriticalSection(int t); // picks up another thread to enter
public static final int TURN_0 = 0; // turn_0 = 1 allows thread 0 to enter
public static final int TURN_1 = 1; // turn_1 = 1 allows thread 1 to enter
}
CSS430 Processes
Synchronization 7
Test Algorithm
(AlgorithmFactory)
public class AlgorithmFactory
{
public static void main(String args[]) {
MutualExclusion alg = new Algorithm_1();
// alg is the shared object including enter/leaveCriticalSection( )
// those CS control methods are actually introduced in the next three slides
Worker first = new Worker("Runner 0", 0, alg);
Worker second = new Worker("Runner 1", 1, alg);
first.start(); // first’s thread id is 0
second.start(); // second’s thread id is 1
}
} CSS430 Processes
Synchronization 8
Algorithm 1 (yielding by
turn)
public class Algorithm_1 extends MutualExclusion {
 Violate CS rule #2, #3 – progress
public Algorithm_1() {  Both thread 0 and 1 cannot enter
turn = TURN_0; CS consecutively.
}
public void enteringCriticalSection(int t) {
while (turn != t) // If it is not my turn,
Thread.yield(); // I will relinquish CPU
}
public void leavingCriticalSection(int t) {
turn = 1 - t; // If I’m thread 0, turn will be 1, otherwise 0
}
private volatile int turn; // turn placed in a register
}
CSS430 Processes
Synchronization 9
Algorithm 2 (saying I’m
using)
public class Algorithm_2 extends MutualExclusion {  Violate CS rule #2, #3 –
public Algorithm_2() { progress
flag[0] = false;  Thread 0 sets flag[0].
flag[1] = false;  A context switch occurs.
}  Thread 1 sets flag[1].
public void enteringCriticalSection(int t) {  Thread 1 finds out
int other = 1 - t; // If I am thread 0, the other is 1 flag[0] is true, and wait
for Thread 0.
flag[t] = true; // I declared I’ll enter CS
 A context switch occurs.
while (flag[other] == true) // If the other is in CS
 Thread 0 finds out
Thread.yield(); // I’ll relinquish CPU.
flag[1] is true, and wait
} for Thread 1.
public void leavingCriticalSection(int t) {
flag[t] = false; // I declared I’m exiting from CS
}
private volatile boolean[] flag = new boolean[2];
} CSS430 Processes
Synchronization 10
Algorithm 3 (Mixed of 1
and 2)
public class Algorithm_3 extends MutualExclusion {
public Algorithm_3( ){ Comply with CS rule

flag[0] = false; #2,3 – progress


flag[1] = false; 
Even in case both
turn = TURN_0; threads declared I’ll
} enter CS, turn
public void enteringCriticalSection( int t ) { eventually points to
int other = 1 - t; // If I am thread 0, the other is 1 either thread A or B!
flag[t] = true; // I declared I’ll enter CS
turn = other; // Yield to another if both threads declared I’l enter CS
while ( ( flag[other] == true ) && ( turn == other ) )
Thread.yield(); // If the other declared and turn is in the other, wait!
}
public void leavingCriticalSection( int t ){ flag[t] = false; }
private volatile int turn;
private volatile boolean[] flag = new boolean[2];
CSS430 Processes
} Synchronization 11
Synchronization Hardware
 Software solutions:
 Algorithm 3:


It works only for a pair of threads. How about a mutual
execution among three or more threads? Check
Lamport’s Algorithm (See Appendix).
 Interrupt Masking:


It disables even time interrupts, thus not allowing
preemption. Malicious user program may hog CPU
forever.
 Hardware solutions:
 Atomic (non-interruptible) set of instructions provided


Test-and-set (or read-modify-write)

Swap
 They are an atomic combination of memory read and

write operations. CSS430 Processes


Synchronization 12
Test (Get) and Set
 Atomic operation:
 Test the value of flag.
 If it is set, leave it ( and wait till it is reset by
the other).
 Else set it (as saying I’ll enter CS.)
 Example:
While ( testAndSet( flag ) == true )
;
// I’ll enter CS.
CSS430 Processes
Synchronization 13
Thread Using Test-and-Set
1. Test and Set 2. Thread Code
public class HardwareData {
HardwareData lock = new
private boolean data; HardwareData(false);
public HardwareData(boolean data) {
this.data = data;
while (true) {
}
while (lock.testAndSet(true))
public boolean get( ) {
return data; Thread.yield(); // do not
} // now in critical section code
public void set(boolean data) { lock.set(false);
this.data = data; // out of critical section
}
public boolean testAndSet(boolean data) { }
boolean oldValue = this.get();
this.set(data);
return oldValue;
}
public void swap(HardwareData other) { /* next page */ }
} CSS430 Processes
Synchronization 14
Swap
 Swapping variables a and b
contents atomically

public void swap(HardwareData other) {


boolean temp = this.get();
this.set(other.get()); // b’s content goes to a
other.set(temp); // a’s content goes to b
}

CSS430 Processes
Synchronization 15
Thread Using Swap
HardwareData lock = new HardwareData(false); // a shared lock 1st Process 2nd Process
HardwareData key = new HardwareData(true); // my key

key key
while (true) { true false true
key.set(true); // my key is now true
do {
I got it!
lock.swap(key); 1st swap 2nd swap
// my key got lock’s content.
} while (key.get() == true); // this means lock was true locked!
criticalSection( ); // now in critical section code
lock.set(false); Lock
nonCriticalSection( ); // out of critical section false true
}

CSS430 Processes
Synchronization 16
Semaphore
 Synchronization tool that does not require busy waiting at a
user level
 Semaphore S – integer variable
 Two standard operations modify S: acquire() and release()
 Originally called P() and V()
 Less complicated
 Can only be accessed
acquire( ) { P (atomic)Voperations
via two indivisible
while value <= 0
; // no-op
value--;
} P V
release( ) {
value++; P V
wakeup( );
}
CSS430 Processes
Synchronization 17
Thread Using Semaphore
public class Worker implements Runnable {
private Semaphore sem;
private String name;
public Worker(Semaphore sem, String name) {
this.sem = sem;
this.name = name;
}
public void run() {
while (true) {
sem.acquire();
MutualExclusionUtilities.criticalSection(name);
sem.release();
MutualExclusionUtilities.nonCriticalSection(name);
} } }
public class SemaphoreFactory { Bee
public static void main(String args[]) {
Semaphore sem = new Semaphore(1); Bee
Thread[] bees = new Thread[5];
for (int i = 0; i < 5; i++)
Bee P V
bees[i] = new Thread( Bee Bee
new Worker(sem,
"Worker " + (new Integer(i)).toString() ));
for (int i = 0; i < 5; i++)
bees[i].start();
} } CSS430 Processes
Synchronization 18
Semaphore Eliminating
Busy-Waiting
Waiting List
acquire(S){
Bee
value--;
if (value < 0) {
Bee
add this process to list
block;
Bee P V
}
}
Bee Bee
release(S){
value++; Waiting List
if (value <= 0) {
remove a process P from list
Bee Wake up one
}
wakeup(P);
Bee
}
Bee P V
Bee Bee
CSS430 Processes
Synchronization 19
Discussion 1
1. Non-interruptible execution of CPU instructions is not enough to
implement TestAndSet and Swap. Why? What else should hardware
support?

2. Can you implement P and V functions using the TestAndSet


instruction? If so, how? Briefly design the algorithm you thought.

3. Fill out the following table.


Advantage Disadvantage Implementation
(HW, OS, or Language)
Test and
set
Swap
Semaphor
e
Monitor

CSS430 Processes
Synchronization 20
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
P(S); P(Q);
P(Q); P(S);
 
V(Q); V(S);
V(S); V(Q);
 Starvation – indefinite blocking. A process may never be
removed from the semaphore queue in which it is suspended.
 What if processes are waiting at P(S) in LIFO order
CSS430 Processes
Synchronization 21
Classical problem 1:
Bounded-Buffer Problem
public class BoundedBuffer {
public BoundedBuffer( ) {
// buffer is initially empty
in = 0; out = 0;
buffer = new Object[BUFFER_SIZE]; // Shared buffer can store five objects.
mutex = new Semaphore( 1 ); // mutex allows only one thread to enter
empty = new Semaphore(BUFFER_SIZE); // empty blocks producer while empty=0
full = new Semaphore( 0 ); // full blocks consumer while full=0
} producer consume
public void insert( ) { /* see next slides */ } empty.P( ) full.P( )
public Object remove( ) { /* see next slides */ }
mutex.P(
(empty--)
)
(full--)
private static final int BUFFER_SIZE = 5; signal signal
private Semaphore mutex, empty, full;
private int in, out;
private Object[] buffer;
mutex.V( )
full.V( ) empty.V( )
} (full++)
CSS430 Processes (empty++)
Synchronization 22
Enter and Remove
methods
public void insert(Object item) {
empty.acquire(); // blocked while empty = 0
mutex.acquire(); // blocked while someone is using mutex, (i.e., in CS)
// add an item to the buffer this is CS
buffer[in] = item;
in = (in + 1) % BUFFER_SIZE;
mutex.release(); // releasing mutex, (i.e., exited from CS)
full.release(); // increment full
}
public Object remove( ) {
full.acquire(); // blocked while full = 0
mutex.acquire(); // blocked while someone is using mutex,
(I.e., in CS)
// remove an item from the buffer this is CS
Object item = buffer[out];
out = (out + 1) % BUFFER_SIZE;
mutex.release(); // releasing mutex, (i.e., exited from CS)
empty.release(); // increment empty
return item; CSS430 Processes
Synchronization 23
}
Producer and Consumer
Threads
import java.util.Date;
public class Producer implements Runnable {
private Buffer buffer;
public Producer(Buffer buffer) {
this.buffer = buffer;
}
public void run() {
Date message;
while (true) {
// nap for awhile
SleepUtilities.nap();
// produce an item & enter it into the buffer
message = new Date();
buffer.insert(message);
} } }
public class Consumer implements Runnable {
private Buffer buffer;
public Consumer(Buffer buffer) {
this.buffer = buffer;
}
public void run() {
Date message;
while (true) {
// nap for awhile
SleepUtilities.nap();
// consume an item from the buffer
message = (Date)buffer.remove();
} } }
CSS430 Processes
Synchronization 24
Bounded Buffer Problem:
Factory

public class Factory


{
public static void main(String args[]) {
Buffer buffer = new BoundedBuffer();
// now create the producer and consumer threads
Thread producer = new Thread(new Producer(buffer));
Thread consumer = new Thread(new Consumer(buffer));
producer.start();
consumer.start();
}
}

CSS430 Processes
Synchronization 25
Monitors
Entry
queue p6 p7 p8
X: p2 p4 p1  High-level language construct
Y: p3 p5  Only one process allowed in a monitor, thus
executing its method
MethodA  A process in the monitor can wait on a
MethodB
MethodC condition variable, say x, thus relinquishing the
x.wait( ); monitor and allowing another process to enter
 A process can signal another process waiting
p1 on a condition variable (on x).
x.signal( )  A process signaling another process should exit
from the monitor, because the signal process
may have begun to work in the monitor.

CSS430 Processes
Synchronization 26
Java Synchronization

public class ClassA { // Every object has a lock associated with it.
public synchronized void method1( ) { // Calling a synchronized method requires “owning” the
lock.
….;
// The lock is released when a thread exits the synchronized method.
}
public Synchronized void method2( ) { // If a calling thread does not own the lock it is placed in
the entry set.
}
private data a, b, c; CSS430 Processes
} Synchronization 27
Java Monitor

public void synchronized method1( ) { // Calling a synchronized method requires “owning” the lock.
// If a calling thread does not own the lock it is placed in the entry s
while ( condition == false )
try {
wait( ); // The thread releases a lock and places itself in the wait set.
} catch( InterruptedException e ) { }
}
….;
notify( ); // The calling thread resumes one of threads waiting in the wait set
}
CSS430 Processes
Synchronization 28
Enter and Remove with
Java Synchronization
Producer Consumer

Public synchronized void insert( Object item ) { Public synchronized Object remove( ) {
while ( count == BUFFER_SIZE ) while ( count == 0 )
try { try {
wait( ); wait( );
} catch ( InterruptedException e ) { } } catch ( InterruptedException e ) { }
} }
++count; CS --count;
buffer[in] = item; item = buffer[out];
in = ( in + 1 ) % BUFFER_SIZE; out = ( out + 1 ) % BUFFER_SIZE;
notify( ); notify( );
} return item;
}

CSS430 Processes
Synchronization 29
Classical Problem 2:
The Readers-Writers
Problem
 Multiple readers or a single writer can use DB.

X X X
writer reader writer reader
reader

writer reader
reader
reader
writer
reader reader

CSS430 Processes
Synchronization 30
Database
public class Database implements RWLock {
public Database( ) {
readerCount = 0; // # readers in database access
dbWriting = false; // a writer in database modification
}
public synchronized void acquireReadLock( ) {
/* A reader can start reading if dbWritng == false */ }
public synchronized void releaseReadLock( ) {
/* A reader exits from database, as waking up a thread */ }
public synchronized void acquireWriteLock( ) {
/* A writer can start writing if dbReading and dbWriting == false */ }
public synchronized void releaseWriteLock( ) {
/* A writer can exit from database, as waking up a thread */ }
private int readerCount;
private boolean dbWriting;
} CSS430 Processes
Synchronization 31
Readers
Condition reader, writer; // introduce condition variables
public synchronized void acquireReadLock( ) {
while (dbWriting == true) {|| !writer.isEmpty(
// while a writer is)in) DB,
{ I have to wait.
try {
reader.wait(
wait( );
) (InterruptedException e) { }
} catch
}
++readerCount;
}

public synchronized void releaseReadLock( ) {


--readerCount
if (readerCount == 0) // if I’m the last reader, tell all others that DB has no more readers.
writer.signal(
notify(); // wake up someone
} )

CSS430 Processes
Synchronization 32
Writers
Public synchronized void ackquireWriteLock( ) {
while (readerCount > 0 || dbWriting == true) // while reader(s) or another write is in DB
try {
wait( );
writer.wait( ) // I have to wait.
} catch ( InterruptedException e ) { }
}
dbWriting = true; // Tell all others that DB is in write.
}

public syncrhonized void releaseWriteLock( ) {


dbWriting = false; // Tell all others that DB is no more in write
If ( !reader.isEmpty(
notifyAll( ); ) ) reader.notify(
// Wake); up
else
all others
wirter.notify( );
}  Why do we have to use notifyAll rather than notify?
 Is this algorithm perfect?
CSS430 Processes
Synchronization 33
Classical Problem 3:
Dining Philosophers
Problem

THINKING
HUNGRY
EATING

 Shared data
Semaphore chopStick[] = new Semaphore[5];

CSS430 Processes
Synchronization 34
The Structure of
Philosopher i
 Philosopher i
while ( true ) {
// get left chopstick
chopStick[i].P();
// get right chopstick
chopStick[(i + 1) %
5].P();

// eat for awhile

//return left chopstick


chopStick[i].V( ); Waiting Picked up
// return right chopstick
chopStick[(i + 1) %
5].V( );
A deadlock occurs!
// think forCSS430
awhileProcesses
} Synchronization 35
Dining-Philosophers
Problem Using a Monitor
monitor DiningPhilosophers {
public entry putDown( int i ) {
int[ ] state = new int[5]; state[i] = THINKING; // I’m stuffed and now thinking.
static final int THINKING = 0; // test lef and right neighbors
test( ( i+4 ) % 5 ); // if possible, wake up my left.
static final int HUNGRY = 1; test( ( i+1 ) % 5 ); // if possible, wake up my right.
}
static final int EATING = 2; private test( int i ) {
condition[ ] self = new condition[5]; // if phi-i’s left is not eating, phi-i is hugry, and
// phi-i’s right is not eating, then phi-i can eat!
public DiningPhilosophers { // Wake up phi-i.
for ( int i = 0; i < 5; i++ ) if ( ( state[( i+4 ) % 5 ] != EATING ) &&
( state[i] == HUNGRY ) &&
state[i] = THINKING; ( state[( i+1 ) % 5] != EATING ) ) {
state[i] = EATING;
} self[i].signal;
public entry pickUp( int i ) { }
}
state[i] = HUNGRY; // I got hungry }
test( i ); // can I have my left and right chopsticks?
if (state[i] != EATING) // no, I can’t, then I should wait
Java monitor has only one condition.
self[i].wait;
}
Thus,
CSS430 this abstract code must be modified
Processes
Synchronization 36
Transactional Memory and
Concurrency Control
 Transactional Memory
 Concurrency Control
CPU A CPU B CPU C CPU D
update ( ) { Trans_start
R1 Compare reads with
atomic { former writes
/* read and write shared data */ R2
Trans_start
} W3
R4 R1
} R2 Trans_start
W5
Compiler-generated code W6
validation R1
R4
CommitmentW7 R2
update ( ) { Trans_start
Trans_end W9
acquire( ); R1
R4
/* read and write shared data */ R2
W8
release( ); Trans_end R6
} R8
W8
Trans_end
Trans_abort
Trans_restart

CSS430 Processes
Synchronization 37
Discussions 2
1. What is the main merit of notifyAll( ) in the
readers-writers problem?

2. Is the solution on pages 30 – 32 perfect for the


readers-writers problem? If not, how can you
improve it?

3. Rather than a monitor, there is the simplest way


that addresses the dining-philosophers problem
but introduces another problem. What is that?

4. If we want to handle multiple monitor conditions


in Java, what classes should you design?
CSS430 Processes
Synchronization 38
Exercises
 Programming Assignment 3:
 Check the syllabus for its due date.
 No-turn-in problems:
 Solve Exercise 6.8, 6.12, 6.13, 6.14,
6.19, and 6.24

CSS430 Processes
Synchronization 39
Appendix
Lamport’s Algorithm
 Available for two or more processes
bool enter[n]; for ( int i = 0; i < n; i++ ) enter[n] = false;
int priority[n]; for ( int i = 0; i < n; i++ ) priority = 0;

Process i:
enter[i] = true;
priority[i] = 1 + max( priority[0], …, priority[n-1] ); // a higher number is a lower priority
enter[i] = false;

for ( int pid = 0; pid < n; pid++ ) {


while ( enter[pid] == true ); // wait for the process pid to receive its priority
while ( priority[pid] != 0 && ( priority[pid] < priority[i] || ( priority[pid] == priority[i] && pid < i ) ) )
// wait if process pid’s priority is higher or its pid is lower than mine.
;
}
// at this point, all the other processes are lower than my priority

// critical section

priority[i] = 0;

CSS543 Lecture 3: Shared Memory 40

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy