+ All Categories
Home > Documents > CENG334 2013 W05 Synchronization Semaphores

CENG334 2013 W05 Synchronization Semaphores

Date post: 03-Jun-2018
Category:
Upload: nurgazy-nazhimidinov
View: 216 times
Download: 0 times
Share this document with a friend
67
1 CENG334 Introduction to Operating Systems Erol Sahin Dept of Computer Eng. Middle East Technical University  Ankara, TURKEY URL:  http://kovan.ce ng.metu.edu .tr/~erol/Cou rses/CENG334 Synchronization Topics: Synchronization problem Race conditions and Critical Sections Mutual exclusion Locks Spinlocks Mutexes Some of the following slides are adapted from Matt Welsh, Harvard Univ.
Transcript
Page 1: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 1/67

1

CENG334

Introduction to Operating Systems

Erol Sahin

Dept of Computer Eng.Middle East Technical University Ankara, TURKEY

URL: http://kovan.ceng.metu.edu.tr/~erol/Courses/CENG334

SynchronizationTopics:

•Synchronization problem

•Race conditions and Critical Sections

•Mutual exclusion

•Locks

•Spinlocks•Mutexes

Some of the following slides are adapted from Matt Welsh, Harvard Univ.

Page 2: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 2/67

2

Single and Multithreaded Processes

Page 3: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 3/67

3

Synchronization

Threads cooperate in multithreaded programs in several ways:

 Access to shared state e.g., multiple threads accessing a memory cache in a Web server

To coordinate their execution e.g., Pressing stop button on browser cancels download of current page

  “stop button thread” has to signal the “download thread” 

For correctness, we have to control this cooperation Must assume threads interleave executions arbitrarily and at different rates

scheduling is not under application’s control

We control cooperation using synchronization

enables us to restrict the interleaving of executions

Page 4: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 4/674

Shared ResourcesWe’ll focus on coordinating access to shared resources

Basic problem: Two concurrent threads are accessing a shared variable

If the variable is read/modified/written by both threads, then access to the variable mustbe controlled

Otherwise, unexpected results may occur

We’ll look at: Mechanisms to control access to shared resources

Low-level mechanisms: locks

Higher level mechanisms: mutexes, semaphores, monitors, and condition variables

Patterns for coordinating access to shared resources

bounded buffer, producer-consumer, … 

This stuff is complicated and rife with pitfalls Details are important for completing assignments

Expect questions on the midterm/final!

Page 5: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 5/675

Shared Variable Example

Suppose we implement a function to withdraw moneyfrom a bank account:

int withdraw(account, amount) {

 balance = get_balance(account);

 balance = balance - amount;

 put_balance(account, balance);

return balance;

}

Now suppose that you and your friend share a bank account with abalance of 1000.00TL

What happens if you both go to separate ATM machines, and simultaneously withdraw

100.00TL from the account?

Page 6: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 6/676

Example continuedWe represent the situation by creating a separate thread  for each ATM

user doing a withdrawal Both threads run on the same bank server system

Thread 1 Thread 2

What’s the problem with this? What are the possible balance values after each thread runs?

int withdraw(account, amount) {

 balance = get_balance(account);

 balance -= amount;

 put_balance(account, balance);

return balance;

}

int withdraw(account, amount) {

 balance = get_balance(account);

 balance -= amount;

 put_balance(account, balance);

return balance;

}

Page 7: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 7/677

Interleaved ExecutionThe execution of the two threads can be inter leaved

 Assume preemptive scheduling

Each thread can context switch after each instruction

We need to worry about the worst-case scenario!

What’s the account balance after this sequence?  And who's happier, the bank or you???

 balance = get_balance(account);

 balance -= amount;

 balance = get_balance(account);

 balance -= amount;

 put_balance(account, balance);

 put_balance(account, balance);

Execution sequence

as seen by CPU context switch

context switch

Page 8: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 8/678

Interleaved ExecutionThe execution of the two threads can be inter leaved

 Assume preemptive scheduling

Each thread can context switch after each instruction

We need to worry about the worst-case scenario!

What’s the account balance after this sequence?  And who's happier, the bank or you???

 balance = get_balance(account);

 balance -= amount;

 balance = get_balance(account);

 balance -= amount;

 put_balance(account, balance);

 put_balance(account, balance);

Execution sequence

as seen by CPU

Balance = 1000TL

Balance = 900TL

Balance = 900TL!

Local = 900TL

Local = 900TL

Page 9: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 9/679

Race Conditions A race occurs when correctness of the program depends on one

thread reaching point x before another thread reaches point y

The problem is that two concurrent threads access a shared resourcewithout any synchronization

This is called a race cond i t ion

The result of the concurrent access is non-deterministic

Result depends on:

Timing

When context switches occurred

Which thread ran at context switch

What the threads were doing

We need mechanisms for controlling access to shared resources in theface of concurrency

This allows us to reason about the operation of programs Essentially, we want to re-introduce determinism into the thread's execution

Synchronization is necessary for any shared data structure buffers, queues, lists, hash tables, … 

Page 10: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 10/6710

Which resources are shared?Local variables in a function are not shared

They exist on the stack, and each thread has its own stack

You can't safely pass a pointer from a local variable to another thread

Why?

Global variables are shared Stored in static data portion of the address space

 Accessible by any thread

Dynamically-allocated data is shared Stored in the heap, accessible by any thread

Stack for thread 0

Heap

Initialized vars(data segment)

Code(text segment)

Uninitialized vars

(BSS segment)

Stack for thread 1

Stack for thread 2

(Reserved for OS)

Shared

Unshared

Page 11: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 11/6711

Mutual Exclusion

We want to use mutual exclusion to synchronize access to sharedresources

Meaning: When only one thread can access a shared resource at a time.

Code that uses mutual exclusion to synchronize its execution iscalled a critical section

Only one thread at a time can execute code in the critical section

 All other threads are forced to wait on entry When one thread leaves the critical section, another can enter

Critical Section

Thread 1

(modify account balance)

Adapted from Matt Welsh s (Harvard University) slides.

M t l E l i

Page 12: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 12/67

12

Mutual Exclusion

We want to use mutual exclusion to synchronize access to sharedresources

Meaning: When only one thread can access a shared resource at a time.

Code that uses mutual exclusion to synchronize its execution iscalled a critical section

Only one thread at a time can execute code in the critical section

 All other threads are forced to wait on entry When one thread leaves the critical section, another can enter

Thread 2

Critical Section

Thread 1

(modify account balance)2nd thread must waitfor critical section to clear

Adapted from Matt Welsh s (Harvard University) slides.

M t l E l i

Page 13: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 13/67

13

Mutual Exclusion

We want to use mutual exclusion to synchronize access to sharedresources

Meaning: When only one thread can access a shared resource at a time.

Code that uses mutual exclusion to synchronize its execution iscalled a critical section

Only one thread at a time can execute code in the critical section

 All other threads are forced to wait on entry When one thread leaves the critical section, another can enter

Critical Section

Thread 1

(modify account balance)

1st thread leaves critical section

Thread 2

2nd thread free to enter

Adapted from Matt Welsh s (Harvard University) slides.

C iti l S ti R i t

Page 14: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 14/67

14

Critical Section RequirementsMutual exclusion

 At most one thread is currently executing in the critical section

Progress If thread T1 is outside the critical section, then T1 cannot prevent T2

from entering the critical section

Bounded waiting (no starvation)

If thread T1 is waiting on the critical section, then T1 will eventually  enter the criticalsection

 Assumes threads eventually leave critical sections

Performance The overhead of entering and exiting the critical section is small with respect to the work

being done within it

Adapted from Matt Welsh s (Harvard University) slides.

L k

Page 15: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 15/67

15

Locks A lock  is a object (in memory) that provides the following two

operations: – acquire( ): a thread calls this before entering a critical section

May require waiting to enter the critical section – release( ): a thread calls this after leaving a critical section

 Allows another thread to enter the critical section

 A call to acquire( ) must have a corresponding call to release( ) Between acquire( ) and release( ), the thread holds the lock

acquire( ) does not return until the caller holds the lock

 At most one thread can hold a lock at a time (usually!)

We'll talk about the exceptions later...

What can happen if acquire( ) and release( ) calls are not paired?

Adapted from Matt Welsh s (Harvard University) slides.

Using Locks

Page 16: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 16/67

16

Using Locks

int withdraw(account, amount) {acquire(lock);

 balance = get_balance(account);

 balance -= amount;

 put_balance(account, balance);

release(lock);

return balance;

}

criticalsection

Adapted from Matt Welsh s (Harvard University) slides.

Execution with Locks

Page 17: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 17/67

17

Execution with Locks

What happens when the blue thread tries to acquire the lock?

acquire(lock);

 balance = get_balance(account);

 balance -= amount;

 balance = get_balance(account);

 balance -= amount;

 put_balance(account, balance);

release(lock);

 put_balance(account, balance);

release(lock);

acquire(lock);

Thread 1 runs

Thread 2 waits on lock

Thread 1 completes

Thread 2 resumes

Adapted from Matt Welsh s (Harvard University) slides.

Spinlocks

Page 18: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 18/67

18

Spinlocks

Very simple way to implement a lock:

Why doesn't this work? Where is the race condition?

struct lock {

int held = 0;

}

void acquire(lock) {

 while (lock->held);

lock->held = 1;

}void release(lock) {

lock->held = 0;

}

The caller busy waitsfor the lock to be released

Adapted from Matt Welsh s (Harvard University) slides.

Implementing Spinlocks

Page 19: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 19/67

19

Implementing SpinlocksProblem is that the internals of the lock acquire/release have critical

sections too! The acquire( ) and release( ) actions must be atomic

 Atomic  means that the code cannot be interrupted during execution   “     All or nothing ”     execution

struct lock {

int held = 0;

}void acquire(lock) {

 while (lock->held);

lock->held = 1;

}

void release(lock) {

lock->held = 0;

}

What can happen if thereis a context switch here?

Adapted from Matt Welsh s (Harvard University) slides.

Implementing Spinlocks

Page 20: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 20/67

20

Implementing SpinlocksProblem is that the internals of the lock acquire/release have critical

sections too! The acquire( ) and release( ) actions must be atomic

 Atomic  means that the code cannot be interrupted during execution   “     All or nothing ”     execution

struct lock {

int held = 0;

}void acquire(lock) {

 while (lock->held);

lock->held = 1;

}

void release(lock) {

lock->held = 0;

}

This sequence needsto be atomic

Adapted from Matt Welsh s (Harvard University) slides.

Implementing Spinlocks

Page 21: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 21/67

21

Implementing SpinlocksProblem is that the internals of the lock acquire/release have critical

sections too! The acquire( ) and release( ) actions must be atomic

 Atomic  means that the code cannot be interrupted during execution   “     All or nothing ”     execution

Doing this requires help from hardware! Disabling interrupts

Why does this prevent a context switch from occurring?  Atomic instructions – CPU guarantees entire action will execute atomically

Test-and-set

Compare-and-swap

Adapted from Matt Welsh s (Harvard University) slides.

Spinlocks using test-and-set

Page 22: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 22/67

22

Spinlocks using test-and-setCPU provides the following as one atomic instruction:

So to fix our broken spinlocks, we do this:

 bool test_and_set(bool *flag) {

… // Hardware dependent implementation }

struct lock {

int held = 0;

}

void acquire(lock) {

 while(test_and_set(&lock->held));

}

void release(lock) {

lock->held = 0;

}

Adapted from Matt Welsh s (Harvard University) slides.

What's wrong with spinlocks?

Page 23: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 23/67

23

What s wrong with spinlocks?

OK, so spinlocks work (if you implement them correctly), and

they are simple. So what's the catch?

struct lock {

int held = 0;

}

void acquire(lock) {

 while(test_and_set(&lock->held));

}

void release(lock) {

lock->held = 0;

}

Adapted from Matt Welsh s (Harvard University) slides.

Problems with spinlocks

Page 24: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 24/67

24

Problems with spinlocks

Horribly wasteful! Threads waiting to acquire locks spin on the CPU

Eats up lots of cycles, slows down progress of other threads

Note that other threads can still run ... how?

What happens if you have a lot of threads trying to acquire the lock?

Only want spinlocks as primitives to build higher-level synchronizationconstructs

Adapted from Matt Welsh s (Harvard University) slides.

Disabling Interrupts

Page 25: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 25/67

25

Disabling Interrupts An alternative to spinlocks:

Can two threads disable/reenable interrupts at the same time?

What's wrong with this approach?

struct lock {

// Note – no state!

}

void acquire(lock) {

cli(); // disable interrupts

}

void release(lock) {

sti(); // reenable interupts}

Adapted from Matt Welsh s (Harvard University) slides.

Disabling Interrupts

Page 26: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 26/67

26

Disabling Interrupts An alternative to spinlocks:

Can two threads disable/reenable interrupts at the same time?

What's wrong with this approach? Can only be implemented at kernel level (why?)

Inefficient on a multiprocessor system (why?)

 All locks in the system are mutually exclusive

No separation between different locks for different bank accounts

struct lock {

// Note – no state!

}

void acquire(lock) {

cli(); // disable interrupts

}

void release(lock) {

sti(); // reenable interupts}

Adapted from Matt Welsh s (Harvard University) slides.

Peterson s Algorithm

Page 27: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 27/67

27

Peterson s Algorithm

flag[0] = 0; flag[1] = 0; turn;

P0:flag[0] = 1;

turn = 1;

while (flag[1] == 1 && turn == 1)

{

// busy wait

}

// critical section

…. 

// end of critical section

flag[0] = 0;

Adapted from Matt Welsh s (Harvard University) slides.

P1:flag[1] = 1;

turn = 0;

 while (flag[0] == 1 && turn == 0)

{

// busy wait

}

// critical section

…. 

// end of critical section

flag[1] = 0;

The algorithm uses two variables,  flag  and turn. A flag value of 1 indicates that the process wants to enter the criticalsection. The variable turn holds the ID of the process whose turn it is. Entrance to the critical section is granted for

 process P0 if P1 does not want to enter its critical section or if P1 has given priority to P0 by setting turn to 0.

Mutexes – Blocking Locks

Page 28: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 28/67

28

  gReally want a thread waiting to enter a critical section to block

Put the thread to sleep until it can enter the critical section

Frees up the CPU for other threads to run

Straightforward to implement using our TCB queues!

Lock wait queue

Thread 1

unlockedLock state

Ø

1) Check lock state???

Adapted from Matt Welsh s (Harvard University) slides.

Mutexes – Blocking Locks

Page 29: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 29/67

29

  gReally want a thread waiting to enter a critical section to block

Put the thread to sleep until it can enter the critical section

Frees up the CPU for other threads to run

Straightforward to implement using our TCB queues!

Lock wait queue

Thread 1

Ø

1) Check lock state

2) Set state to locked

3) Enter critical section

lockedLock state

Adapted from Matt Welsh s (Harvard University) slides.

Mutexes – Blocking Locks

Page 30: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 30/67

30

gReally want a thread waiting to enter a critical section to block

Put the thread to sleep until it can enter the critical section

Frees up the CPU for other threads to run

Straightforward to implement using our TCB queues!

Lock wait queue

Thread 1

Ø

1) Check lock state

lockedLock state

Thread 2

???

Adapted from Matt Welsh s (Harvard University) slides.

Mutexes – Blocking Locks

Page 31: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 31/67

31

gReally want a thread waiting to enter a critical section to block

Put the thread to sleep until it can enter the critical section

Frees up the CPU for other threads to run

Straightforward to implement using our TCB queues!

Lock wait queue

Thread 1

1) Check lock state

lockedLock state

Thread 2 2) Add self to wait queue (sleep)

Thread 2

Ø

Adapted from Matt Welsh s (Harvard University) slides.

Mutexes –

 Blocking Locks

Page 32: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 32/67

32

Really want a thread waiting to enter a critical section to block Put the thread to sleep until it can enter the critical section

Frees up the CPU for other threads to run

Straightforward to implement using our TCB queues!

Lock wait queue

Thread 1

1) Check lock state

lockedLock state

Thread 3 2) Add self to wait queue (sleep)

Thread 2

???

Thread 3

Adapted from Matt Welsh s (Harvard University) slides.

Mutexes –

 Blocking Locks

Page 33: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 33/67

33

Really want a thread waiting to enter a critical section to block Put the thread to sleep until it can enter the critical section

Frees up the CPU for other threads to run

Straightforward to implement using our TCB queues!

Lock wait queue

Thread 1

1) Thread 1 finishes critical section

lockedLock state

Thread 2 Thread 3

Adapted from Matt Welsh s (Harvard University) slides.

Mutexes –

 Blocking Locks

Page 34: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 34/67

34

Really want a thread waiting to enter a critical section to block Put the thread to sleep until it can enter the critical section

Frees up the CPU for other threads to run

Straightforward to implement using our TCB queues!

Lock wait queue

Thread 1

1) Thread 1 finishes critical section

2) Reset lock state to unlocked

Thread 2 Thread 3

3) Wake one thread from wait queue

unlockedLock state

Thread 3

Adapted from Matt Welsh s (Harvard University) slides.

Mutexes –

 Blocking Locks

Page 35: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 35/67

35

Really want a thread waiting to enter a critical section to block Put the thread to sleep until it can enter the critical section

Frees up the CPU for other threads to run

Straightforward to implement using our TCB queues!

Lock wait queue

Thread 3 can now grab lock andenter critical section

Thread 2

Thread 3

lockedLock state

Adapted from Matt Welsh s (Harvard University) slides.

Limitations of locks

Page 36: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 36/67

36

Locks are great, and simple. What can they not easily accomplish?

What if you have a data structure where it's OK for many threads

to read the data, but only one thread to write the data? Bank account example.

Locks only let one thread access the data structure at a time.

Adapted from Matt Welsh s (Harvard University) slides.

Limitations of locks

Page 37: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 37/67

37

Locks are great, and simple. What can they not easily accomplish?

What if you have a data structure where it's OK for many threads

to read the data, but only one thread to write the data? Bank account example.

Locks only let one thread access the data structure at a time.

What if you want to protect access to two (or more)

data structures at a time? e.g., Transferring money from one bank account to another.

Simple approach: Use a separate lock for each.

What happens if you have transfer from account A -> account B, at the same timeas transfer from account B -> account A?

Hmmmmm ... tricky.

We will get into this next time.

Adapted from Matt Welsh s (Harvard University) slides.

Now..

Page 38: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 38/67

38

Higher level synchronization primitives:How do to fancier stuff than just locks

Semaphores, monitors, and condition variables Implemented using basic locks as a primitive

 Allow applications to perform more complicated coordination schemes

Adapted from Matt Welsh s (Harvard University) slides.Adapted from Matt Welsh s (Harvard University) slides.

Page 39: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 39/67

393

CENG 4

Introduction to Operating Systems

Erol Sahin

Dept of Computer Eng.Middle East Technical University

 Ankara, TURKEY

URL: http://kovan.ceng.metu.edu.tr/~erol/Courses/CENG334

SemaphoresTopics:

• Need for higher-level synchronization primitives

•Semaphores and their implementation

•The Producer/Consumer problem and its solution with semaphores

•The Reader/Writer problem and its solution with semaphores

Some of the following slides are adapted from Matt Welsh, Harvard Univ.

Higher-level synchronization primitivesWe ha e looked at one s nchroni ation primiti e locks

Page 40: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 40/67

40

We have looked at one synchronization primitive: locks

Locks are useful for many things, but sometimes programs have

different requirements.

Examples? Say we had a shared variable where we wanted any number of threads to read  

the variable, but only one thread  to wri te  it.

How would you do this with locks?

What's wrong with this code?

Reader() {lock.acquire(); mycopy = shared_var;lock.release();return mycopy;

}

 Writer() {lock.acquire();shared_var = NEW_VALUE;lock.release();

}

Adapted from Matt Welsh s (Harvard University) slides.

SemaphoresHigher level synchronization

Page 41: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 41/67

41

Higher-level synchronizationconstruct

Designed by Edsger Dijkstra in the1960's, part of the THE operating

system (classic stuff!)

Semaphore is a shared counter

Two operations on semaphores:

P() or wait() or down() From Dutch “     proeberen”    , meaning “    test ”     

 Atomic action:

Wait for semaphore value to become > 0, then decrement it

V() or signal() or up() From Dutch “    verhogen”    , meaning “    increment ”     

 Atomic action:

Increments semaphore value by 1.

Semaphore

Adapted from Matt Welsh s (Harvard University) slides.

Semaphore ExampleSemaphores can be used to implement locks:

Page 42: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 42/67

42

Semaphores can be used to implement locks:

 A semaphore where the counter value is only 0 or 1 iscalled a binary semaphore.

int withdraw(account, amount) {

down(my_semaphore);

 balance = get_balance(account);

 balance -= amount;

 put_balance(account, balance);

up(my_semaphore);

return balance;

}

criticalsection

Semaphore my_semaphore = 1; // Initialize to nonzero

Adapted from Matt Welsh s (Harvard University) slides.

Simple Semaphore Implementation

Page 43: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 43/67

43

What's wrong with this picture???

struct semaphore {int val;threadlist L; // List of threads waiting for semaphore

}

down(semaphore S): // Wait until > 0 then decrementif (S.val <= 0) {

add this thread to S.L; block(this thread);

}S.val = S.val -1;return;

up(semaphore S): // Increment value and wake up next thread

S.val = S.val + 1;if (S.L is nonempty) {

remove a thread T from S.L; wakeup(T);

}

Adapted from Matt Welsh s (Harvard University) slides.

Simple Semaphore Implementation

Page 44: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 44/67

44

down() and

up() must beatomicactions!

struct semaphore {int val;threadlist L; // List of threads waiting for semaphore

}

down(semaphore S): // Wait until > 0 then decrement while (S.val <= 0) {

add this thread to S.L;

 block(this thread);

}

S.val = S.val -1;

return;

up(semaphore S): // Increment value and wake up next thread

S.val = S.val + 1;if (S.L is nonempty) {remove a thread T from S.L;

 wakeup(T);

}

Adapted from Matt Welsh s (Harvard University) slides.

Page 45: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 45/67

Semaphore Implementation

Page 46: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 46/67

46

How do we ensure that the semaphore implementation is atomic?

One approach: Make them system calls, and ensure only one

down() or up() operation can be executed by any process at atime.

This effectively puts a lock around the down() and up() operations themselves!

Easy to do by disabling interrupts in the down() and up() calls.

 Another approach: Use hardware support Say your CPU had atomic down and up instructions

Adapted from Matt Welsh s (Harvard University) slides.

OK, but why are semaphores useful?

A binary semaphore (counter is always 0 or 1) is basically a

Page 47: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 47/67

47

 A binary semaphore (counter is always 0 or 1) is basically alock.

The real value of semaphores becomes apparent when thecounter can be initialized to a value other than 0 or 1.

Say we initialize a semaphore's counter to 50. What does this mean about down() and up() operations?

Adapted from Matt Welsh s (Harvard University) slides.

The Producer/Consumer ProblemAlso called the Bounded Buffer problem.

Page 48: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 48/67

48

 Also called the Bounded Buffer problem.

Producer pushes items into the buffer.

Consumer pulls items from the buffer.

Producer needs to wait when buffer is full.

Consumer needs to wait when the buffer is empty.

Producer Consumer

Mmmm... donuts

Adapted from Matt Welsh s (Harvard University) slides.

The Producer/Consumer Problem Also called the Bounded Buffer problem.

Page 49: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 49/67

49

p

Producer pushes items into the buffer.

Consumer pulls items from the buffer.

Producer needs to wait when buffer is full.

Consumer needs to wait when the buffer is empty.

Producer Consumer

zzzzz....

Adapted from Matt Welsh s (Harvard University) slides.

One implementation...

Page 50: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 50/67

50

Producer Consumer

int count = 0;

Producer() {int item;

 while (TRUE) {item = bake();if (count == N) sleep();insert_item(item);count = count + 1;if (count == 1)

 wakeup(consumer);

}}

Consumer() {int item; while (TRUE) {

if (count == 0) sleep();item = remove_item();count = count – 1;if (count == N-1)

 wakeup(producer);eat(item);

}}

What's wrong with this code?What if we context switch right here??

Adapted from Matt Welsh s (Harvard University) slides.

A fix using semaphores

Page 51: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 51/67

51

Producer Consumer

Semaphore mutex = 1;Semaphore empty = N;Semaphore full = 0;

Producer() {int item; while (TRUE) {

item = bake();down(empty);down(mutex);insert_item(item);

up(mutex);up(full);}}

Consumer() {

int item; while (TRUE) {

down(full);down(mutex);item = remove_item();up(mutex);up(empty);

eat(item);}}

Adapted from Matt Welsh s (Harvard University) slides.

Reader/Writers

f

Page 52: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 52/67

52

Let's go back to the problem at the beginning of lecture. Single shared object

Want to allow any number of threads to read simultaneously

But, only one thread should be able to write to the object at a time

(And, not interfere with any readers...)

Semaphore mutex = 1;

Semaphore wrt = 1;

int readcount = 0;

 Writer() {down(wrt);do_write();up(wrt); }

Reader() {down(mutex); readcount++;if (readcount == 1) {

down(wrt);}up(mutex);do_read();down(mutex); readcount--;

if (readcount == 0) {up(wrt);

}up(mutex);

}

Why the testhere??

Adapted from Matt Welsh s (Harvard University) slides.

✔ A Reader should only wait for a Writer to complete itsdo_write().✔ A Reader should not wait for other Readers to complete theirdo_read().✔ The Writer should wait for the other Writers to complete theirdo_write().✔ The Writer should wait for all the Readers to complete theirdo_read().

Issues with SemaphoresMuch of the power of semaphores derives from calls to

Page 53: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 53/67

53

p pdown() and up() that are unmatched

See previous example!

Unlike locks, acquire() and release() are not always paired.

This means it is a lot easier to get into trouble with semaphores.   “More rope” 

Would be nice if we had some clean, well-defined languagesupport  for synchronization...

Java does!

Adapted from Matt Welsh s (Harvard University) slides.

CENG334

Page 54: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 54/67

54

Introduction to Operating Systems

Erol Sahin

Dept of Computer Eng.

Middle East Technical UniversityAnkara, TURKEY

URL: http://kovan.ceng.metu.edu.tr/ceng334

Synchronization patternsTopics•Signalling•Rendezvous•Barrier

SignallingPossibly the simplest use for a semaphore is signaling, which means

Page 55: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 55/67

55

y p p g g,

that one thread sends a signal to another thread to indicate that

something has happened.

Signaling makes it possible to guarantee that a section of code in

one thread will run before a section of code in another thread; in

other words, it solves the serialization problem.

Adapted from The Little Book of Semaphores.

SignallingImagine that a1 reads a line from a file, and b1 displays the line on the screen.

Page 56: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 56/67

56

The semaphore in this program guarantees that Thread A has completed a1before Thread B begins b1.

Here’s how it works: if thread B gets to the wait statement first, it will find the initialvalue, zero, and it will block. Then when Thread A signals, Thread B proceeds.

Similarly, if Thread A gets to the signal first then the value of the semaphore willbe incremented, and when Thread B gets to the wait, it will proceed immediately.

Either way, the order of a1 and b1 is guaranteed.

Thread A

statement a1;

sem.up();

Thread B

sem.down();

statement b1;

semaphore sem=0;

Adapted from The Little Book of Semaphores.

RendezvousGeneralize the signal pattern so that it works both ways. Thread A

Page 57: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 57/67

57

g p y

has to wait for Thread B and vice versa. In other words, given this

code we want to guarantee that a1 happens before b2 and b1

happens before a2.

Your solution should not enforce too many constraints. For example,

we don’t care about the order of a1 and b1. In your solution, eitherorder should be possible.

Two threads rendezvous at a point of execution, and neither is

allowed to proceed until both have arrived.

Thread A

statement a1;

statement a2;

Thread B

statement b1;

statement b2;

Adapted from The Little Book of Semaphores.

Rendezvous - HintGeneralize the signal pattern so that it works both ways. Thread A has to wait for

Thread B and vice versa. In other words, given this code we want to guarantee that

Page 58: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 58/67

58

Thread B and vice versa. In other words, given this code we want to guarantee thata1 happens before b2 and b1 happens before a2.

Your solution should not enforce too many constraints. For example, we don’t care

about the order of a1 and b1. In your solution, either order should be possible.

Two threads rendezvous at a point of execution, and neither is allowed to proceed untilboth have arrived.

Hint: Create two semaphores, named aArrived and bArrived, and initialize them bothto zero. aArrived indicates whether Thread A has arrived at the rendezvous, andbArrived likewise.

Thread A

statement a1;

statement a2;

Thread B

statement b1;

statement b2;

semaphore aArrived=0;

semaphore bArrived=0;

Adapted from The Little Book of Semaphores.

Rendezvous - SolutionGeneralize the signal pattern so that it works both ways. Thread A has to wait for

Thread B and vice versa In other words given this code we want to guarantee

Page 59: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 59/67

59

Thread B and vice versa. In other words, given this code we want to guaranteethat a1 happens before b2 and b1 happens before a2.

Your solution should not enforce too many constraints. For example, we don’tcare about the order of a1 and b1. In your solution, either order should be

possible.

Two threads rendezvous at a point of execution, and neither is allowed to proceeduntil both have arrived.

Hint: Create two semaphores, named aArrived and bArrived, and initialize themboth to zero. aArrived indicates whether Thread A has arrived at the rendezvous,and bArrived likewise.

Thread A

statement a1;

aArrived.up();

 bArrived.down();

statement a2;

Thread B

statement b1;

 bArrived.up();

aArrived.down();

statement b2;

semaphore aArrived=0;

semaphore bArrived=0;

Adapted from The Little Book of Semaphores.

Rendezvous –

 A less efficient solutionThis solution also works, although it is probably less efficient, since it

might have to switch between A and B one time more than

Page 60: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 60/67

60

might have to switch between A and B one time more thannecessary.

If A arrives first, it waits for B. When B arrives, it wakes A and mightproceed immediately to its wait in which case it blocks, allowing Ato reach its signal, after which both threads can proceed..

Thread A

statement a1

 bArrived.down() 

aArrived.up() 

statement a2

Thread B

statement b1;

 bArrived.up();

aArrived.down();

statement b2;

semaphore aArrived=0;

semaphore bArrived=0;

Adapted from The Little Book of Semaphores.

Rendezvous –

 How about?

Page 61: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 61/67

61

Thread A

statement a1

 bArrived.down() 

aArrived.up() 

statement a2

Thread B

statement b1;

aArrived.down();

 bArrived.up();

statement b2;

semaphore aArrived=0;

semaphore bArrived=0;

Adapted from The Little Book of Semaphores.

BarrierRendezvous solution does not work with more than two threads.

Page 62: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 62/67

62

rendezvous();

criticalpoint();

Puzzle: Generalize the rendezvous solution. Every thread should runthe following code:

The synchronization requirement is that no thread executes critical pointuntil after all threads have executed rendezvous.

You can assume that there are n threads and that this value is stored in avariable, n, that is accessible from all threads.

When the first n − 1 threads arrive they should block until the nth thread

arrives, at which point all the threads may proceed.

Adapted from The Little Book of Semaphores.

Barrier - Hint

Page 63: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 63/67

63

n = thenumberofthreads;

count = 0;

Semaphore mutex=1, barrier=0;

count keeps track of how many threads have arrived. mutex

provides exclusive access to count so that threads can increment itsafely.

barrier is locked (zero or negative) until all threads arrive; then itshould be unlocked (1 or more).

Adapted from The Little Book of Semaphores.

Barrier –

 Solution?n = thenumberofthreads;

t 0

Page 64: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 64/67

64

count = 0;

Semaphore mutex=1, barrier=0;

rendezvous();

 mutex.down();

count = count + 1;

 mutex.up();

if (count == n) barrier.up();

else barrier.down();

Criticalpoint();

Since count is protected by a mutex, it counts the number of threads

that pass. The first n−1 threads wait when they get to the barrier,which is initially locked. When the nth thread arrives, it unlocks thebarrier.

What is wrong with this solution?

Adapted from The Little Book of Semaphores.

Barrier –

 Solution?n = thenumberofthreads;

count 0;

Page 65: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 65/67

65

count = 0;

Semaphore mutex=1, barrier=0;

rendezvous();

 mutex.down();

count = count + 1;

 mutex.up();

if (count == n) barrier.up();

else barrier.down();

Criticalpoint();

Imagine that n = 5 and that 4 threads are waiting at the barrier. The value of the

semaphore is the number of threads in queue, negated, which is -4.

When the 5th thread signals the barrier, one of the waiting threads is allowed toproceed, and the semaphore is incremented to -3. But then no one signals thesemaphore again and none of the other threads can pass the barrier.

Adapted from The Little Book of Semaphores.

Barrier –

 Solutionn = thenumberofthreads;

count = 0;

Page 66: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 66/67

66

count = 0;

Semaphore mutex=1, barrier=0;

rendezvous();

 mutex.down();

count = count + 1;

 mutex.up();

if (count == n) barrier.up();

else{

 barrier.down();

 barrier.up();

}

Criticalpoint();

The only change is another signal after waiting at the barrier. Nowas each thread passes, it signals the semaphore so that the nextthread can pass.

Adapted from The Little Book of Semaphores.

Barrier –

 Bad Solutionn = thenumberofthreads;

count = 0;

Page 67: CENG334 2013 W05 Synchronization Semaphores

8/12/2019 CENG334 2013 W05 Synchronization Semaphores

http://slidepdf.com/reader/full/ceng334-2013-w05-synchronization-semaphores 67/67

67

count = 0;

Semaphore mutex=1, barrier=0;

rendezvous();

 mutex.down();

count = count + 1;

if (count == n) barrier.up();

 barrier.down();

 barrier.up();

 mutex.up();

Criticalpoint();

Imagine that the first thread enters the mutex and then blocks. Sincethe mutex is locked, no other threads can enter, so the condition,count==n, will never be true and no one will ever unlock.

Adapted from The Little Book of Semaphores.


Recommended