22
COMP346/5461 - Operating Systems Revision 1.3 Feb 3rd, 2010 10/27/2012 Serguei A. Mokhov, [email protected] 1

COMP346/5461 - Operating Systemsaimanhanna.com/concordia/comp346/Synchronization.pdf · while other process is waiting for that lock. Proper synchronization helps to avoid race conditions

  • Upload
    others

  • View
    6

  • Download
    0

Embed Size (px)

Citation preview

COMP346/5461 - Operating Systems

Revision 1.3

Feb 3rd, 2010

10/27/2012 Serguei A. Mokhov, [email protected] 1

Topics Synchronization in Details

Semaphores

Introducing Semaphore.java

10/27/2012 Serguei A. Mokhov, [email protected] 2

Synchronization What is it?

An act of communication between unrelated processes to sync their activities to achieve some goals and solve some common problems of multiprogramming: Mutual exclusion and critical sections

Specific execution order must be maintained

Improper sync may cause a very big problem in all Operating Systems – a deadlock.

10/27/2012 Serguei A. Mokhov, [email protected] 3

Synchronization Improper synchronization leads to

a corruption to shared file / object / data.

Deadlock , one process holds a lock for long long time while other process is waiting for that lock.

Proper synchronization helps to avoid race conditions.

Our goal is to

Synchronize between process and

Maximize concurrency.

Make the CPU busy doing useful tasks most of the time.

10/27/2012 Serguei A. Mokhov, [email protected] 4

A Typical Example Shared account (between spouses John and Jane)

Current account balance: $400

John and Jane happened to be at the ATM in different places, but at almost the same time.

Let say John wants to withdraw $200, and Jane wants to withdraw $300.

First scenario: both of them see the current balance of $400 and relatively at the same time perform request to withdraw. John goes first…

10/27/2012 Serguei A. Mokhov, [email protected] 5

A Typical Example (2) A DB system takes $400, subtracts $200, and gets

interrupted (e.g. network congestion), thus the remaining balance of $200 wasn’t recorded yet.

Jane’s request goes through and the system writes down $100 balance remaining.

Then John’s request finally goes through, and system updates the balance to $200.

The bank is a victim in that case because John and Jane were able to withdraw $500 and have $200 remaining, when initially account’s balance was $400!

10/27/2012 Serguei A. Mokhov, [email protected] 6

A Typical Example (4)

10/27/2012 Serguei A. Mokhov, [email protected] 7

class John extends Thread {

run() {

balance = ATM.getBalance();

if(balance >= $200)

ATM.withdraw($200);

}

}

class Jane extends Thread {

run() {

balance = ATM.getBalance();

if(balance >= $300)

ATM.withdraw($300);

}

}

class ATM{ …

int withdraw(amount){

if(amount <= balance) {

balance = balance – amount;

return amount;

}

}

A trouble may occur at

the points marked with

the red arrows. The code

MUST NOT be interrupted

at those places.

Solution: Use Semaphores Obvious: make the critical section part atomic.

One way of doing it: Semaphores

Semaphores are system-wide OS objects (also resources) used to Protect critical section (mutexes – for Mutual

Exclusion),

Coordinate other process’ activities.

Semaphores are NOT shared memory segments! But they both are often used together.

10/27/2012 Serguei A. Mokhov, [email protected] 8

Semaphores for CS There are two main operations on semaphores – Wait() and Signal().

A process wishing to enter the critical section tries to acquire the semaphore (a lock in a human world) by calling Wait(sem), sem.Wait() (a.k.a. P()). If the lock isn’t there (i.e. “in use”), the execution of the process calling

Wait() is suspended (put asleep). Otherwise, it acquires the semaphore and does the CS stuff.

When a process is over with the CS, it notifies the rest of the processes waiting on the same semaphore that they can go in by calling Signal(sem), Sem.signal() (a.k.a. V()).

The awakened process goes back to the ready queue to compete again to enter the CS.

10/27/2012 Serguei A. Mokhov, [email protected] 9

A Typical Example Solution

10/27/2012 Serguei A. Mokhov, [email protected] 10

class John extends Thread {

run() {

mutex.Wait();

balance = ATM.getBalance();

if(balance >= $200)

ATM.withdraw($200);

mutex.Signal();

}

}

class Jane extends Thread {

run() {

mutex.Wait();

balance = ATM.getBalance();

if(balance >= $300)

ATM.withdraw($300);

mutex.Signal();

}

}

class ATM{ …

Semaphore mutex = 1;

int withdraw(amount) {

if(amount <= balance) {

balance = balance – amount;

return amount;

}

}

A trouble may occur at

the points marked with

red. The code MUST NOT be

interrupted at those places.

Semaphores for Barrier Sync Take a look at the typical problem:

all processes must finish their phase I before any of

them starts phase II

processes must proceed to their phase II in a specific order, for example: 1, 2, 3…

This is called barrier synchronization.

10/27/2012 Serguei A. Mokhov, [email protected] 11

semaphore s1 = 0, s2 = 0;

process P1 process P2

<phase I> <phase I>

V (s1) V (s2)

P (s2) P (s1)

<phase II> <phase II>

Barrier Sync for Three Processes A possible copy-cat attempt:

Why it doesn’t work?

10/27/2012 Serguei A. Mokhov, [email protected] 12

semaphore s1 = 0, s2 = 0, s3 = 0;

process P1 process P2 process P3

<phase I> <phase I> <phase I>

V (s1) V (s2) V (s3)

P (s3) P (s1) P (s2)

<phase II> <phase II> <phase II>

Barrier Sync for Three Processes A possible copy-cat attempt:

Why it doesn’t work?

Scenario: 1-6 , process 2 even hasn’t started!

None of the requirements are met

10/27/2012 Serguei A. Mokhov, [email protected] 13

semaphore s1 = 0, s2 = 0, s3 = 0;

process P1 process P2 process P3

3 <phase I> <phase I> 1 <phase I>

4 V (s1) V (s2) 2 V (s3)

5 P (s3) P (s1) P (s2)

6 <phase II> <phase II> <phase II>

Barrier Sync for Three Processes (2) Another attempt:

What’s wrong now?

10/27/2012 Serguei A. Mokhov, [email protected] 14

semaphore s1 = 0, s2 = 0, s3 = 0;

process P1 process P2 process P3

<phase I> <phase I> <phase I>

P (s1) V (s1) V (s1)

P (s1) P (s2) P (s3)

V (s2) V (s3)

<phase II> <phase II> <phase II>

Barrier Sync for Three Processes (2) Another attempt:

What’s wrong now?

Scenario: 1-10, so far so good, but after…

The second requirement isn’t met

10/27/2012 Serguei A. Mokhov, [email protected] 15

semaphore s1 = 0, s2 = 0, s3 = 0;

process P1 process P2 process P3

7 <phase I> 4 <phase I> 1 <phase I>

8 P (s1) 5 V (s1) 2 V (s1)

9 P (s1) 6 P (s2) 3 P (s3)

10 V (s2) V (s3)

<phase II> <phase II> <phase II>

Barrier Sync for Three Processes (3)

Last attempt:

A bit “optimized”:

10/27/2012 Serguei A. Mokhov, [email protected] 16

semaphore s1 = 0, s2 = 0, s3 = 0;

process P1 process P2 process P3

<phase I> <phase I> <phase I>

P (s1) V (s1) V (s1)

P (s1) P (s2) P (s3)

<phase II> <phase II> <phase II>

V (s2) V (s3)

semaphore s1 = -1, s2 = 0, s3 = 0;

process P1 process P2 process P3

<phase I> <phase I> <phase I>

V (s1) V (s1)

P (s1) P (s2) P (s3)

<phase II> <phase II> <phase II>

V (s2) V (s3)

Barrier Sync: Need for the General Solution

Problem with the proposed solution: # of semaphores == # of processes.

Semaphores as any other resource are limited and take space => overhead

Imagine you need to sync 10 processes in the same manner? 100? 1000? Complete mess and a high possibility of a deadlock!

10/27/2012 Serguei A. Mokhov, [email protected] 17

Barrier Sync: Need for the General Solution (2)

Attempt for the first requirement:

The second requirement is left as an exercise to the curious student :-)

10/27/2012 Serguei A. Mokhov, [email protected] 18

semaphore s1 = -n + 2, s2 = 0;

process P1 process P2 ... process Pn

<phase I> <phase I> ... <phase I>

P (s1) V (s1) ... V (s1)

V (s2) P (s2) ... P (s2)

V (s2) ... V (s2)

<phase II> <phase II> ... <phase II>

Introducing the Semaphore Class

NOTE: Operations Signal and Wait are

guaranteed to be atomic!

10/27/2012 Serguei A. Mokhov, [email protected] 19

class Semaphore { private int value; public Semaphore(int value) { this.value = value; } public Semaphore() { this(0); } ...

Introducing the Semaphore Class (2)

10/27/2012 Serguei A. Mokhov, [email protected] 20

... public synchronized void Wait() { while(this.value <= 0) { try { wait(); } catch(InterruptedException e) { System.out.println ( "Semaphore::Wait() …” + e.getMessage() ); e.printStackTrace(); } } this.value--; } ...

Introducing the Semaphore Class (3)

10/27/2012 Serguei A. Mokhov, [email protected] 21

... public synchronized void Signal() { ++this.value; notify(); } public synchronized void P() { this.Wait(); } public synchronized void V() { this.Signal(); } }

References http://users.encs.concordia.ca/~mokhov/comp346

/

10/27/2012 Serguei A. Mokhov, [email protected] 22