semaphores os basics

44
Copyright ©: University of Illinois CS 241 Staff 1 Synchronization and Semaphores

Upload: shijin-raj-p

Post on 12-Apr-2017

814 views

Category:

Education


3 download

TRANSCRIPT

Page 1: Semaphores OS Basics

Copyright ©: University of Illinois CS 241 Staff 1

Synchronization and Semaphores

Page 2: Semaphores OS Basics

Discussion

In uni-processors Concurrent processes cannot be overlapped, only interleaved A process runs until it invokes a system call, or is interrupted To guarantee mutual exclusion, hardware support could help

by allowing the disabling of interruptsWhile(true) { /* disable interrupts */ /* critical section */ /* enable interrupts */ /* remainder */}

What’s the problem with this solution?

2Copyright ©: University of Illinois CS 241 Staff

Page 3: Semaphores OS Basics

Discussion

In multi-processors Several processors share memory Processors behave independently in a peer relationship Interrupt disabling will not work We need hardware support where access to a memory

location excludes any other access to that same location The hardware support is based on execution of multiple

instructions atomically (test and set)

3Copyright ©: University of Illinois CS 241 Staff

Page 4: Semaphores OS Basics

Test and Set Instruction

boolean Test_And_Set(boolean* lock) atomic {

boolean initial;initial = *lock;*lock = true;return initial;

}

Note: this is more accuratethan the textbook version

atomic = executed in a single shot without any interruption

4Copyright ©: University of Illinois CS 241 Staff

Page 5: Semaphores OS Basics

Using Test_And_Set for Mutual Exclusion

Pi {while(1) {while(Test_And_Set(lock)) { /* spin */

}

/* Critical Section */ lock =0; /* remainder */

} }

void main () {lock = 0; parbegin(P1,…,Pn);

}

5

What's the problem?

Copyright ©: University of Illinois CS 241 Staff

Page 6: Semaphores OS Basics

Using Test_And_Set for Mutual Exclusion

Pi {while(1) {while(Test_And_Set(lock)) { /* spin */

}

/* Critical Section */ lock =0; /* remainder */

} }

void main () {lock = 0; parbegin(P1,…,Pn);

}

Works, but has performance loss because of busy waiting.6Copyright ©: University of Illinois CS 241 Staff

Page 7: Semaphores OS Basics

Semaphores

Fundamental Principle: Two or more processes want to

cooperate by means of simple signals Special Variable: semaphore s

A special kind of “int” variable Can’t just modify or set or increment or

decrement it

7Copyright ©: University of Illinois CS 241 Staff

Page 8: Semaphores OS Basics

Semaphores

Before entering critical section semWait(s)

Receive signal via semaphore s “down” on the semaphore Also: P – proberen

After finishing critical section semSignal(s)

Transmit signal via semaphore s “up” on the semaphore Also: V – verhogen

Implementation requirements semSignal and semWait must be atomic

8Copyright ©: University of Illinois CS 241 Staff

Page 9: Semaphores OS Basics

Semaphores vs. Test_and_SetSemaphoresemaphore s = 1; Pi {

while(1) { semWait(s); /* Critical Section

*/semSignal(s);/* remainder */

}}

Test_and_Setlock = 0;Pi {

while(1) {while(Test_And_Set(lock));

/* Critical Section */ lock =0; /* remainder */

} }

9Copyright ©: University of Illinois CS 241 Staff

Avoid busy waiting by suspending Block if s == False Wakeup on signal (s = True)

Page 10: Semaphores OS Basics

Inside a Semaphore

Requirement No two processes can execute wait() and signal()

on the same semaphore at the same time!

Critical section wait() and signal() code Now have busy waiting in critical section implementation

Implementation code is short Little busy waiting if critical section rarely occupied Bad for applications may spend lots of time in critical sections

Copyright ©: University of Illinois CS 241 Staff 10

Page 11: Semaphores OS Basics

Inside a Semaphore

Add a waiting queue Multiple process

waiting on s Wakeup one of the

blocked processes upon getting a signal

Semaphore data structuretypedef struct {

int count;queueType queue; /* queue for procs. waiting on s */

} SEMAPHORE;

11Copyright ©: University of Illinois CS 241 Staff

Page 12: Semaphores OS Basics

Binary Semaphorestypedef struct bsemaphore {

enum {0,1} value;queueType queue;

} BSEMAPHORE;

void semSignalB (bsemaphore s) {if (s.queue is empty())s.value = 1;else {remove P from s.queue;place P on ready list; }

}

void semWaitB(bsemaphore s) {if (s.value == 1)

s.value = 0;else {

place P in s.queue;block P;

}}

12Copyright ©: University of Illinois CS 241 Staff

Page 13: Semaphores OS Basics

General Semaphoretypedef struct {

int count; queueType queue;

} SEMAPHORE;

void semSignal(semaphore s) {s.count++;if (s.count ≤ 0) {remove P from s.queue;place P on ready list; }

}

void semWait(semaphore s) {s.count--;

if (s.count < 0) {place P in s.queue;block P;

}}

13Copyright ©: University of Illinois CS 241 Staff

Page 14: Semaphores OS Basics

void semWait(semaphore s) {s.count--;

if (s.count < 0) {place P in s.queue;block P;

}}

Making the operations atomic

Isn’t this exactly what semaphores were trying to solve? Are we stuck?!

Solution: resort to test-and-set

14

typedef struct { boolean lock; int count; queueType queue; } SEMAPHORE;

void semWait(semaphore s) { while (test_and_set(lock)) { } s.count--; if (s.count < 0) { place P in s.queue; block P; } lock = 0;}

Copyright ©: University of Illinois CS 241 Staff

Page 15: Semaphores OS Basics

Making the operations atomic

Busy-waiting again! Then how are

semaphores better than just using test_and_set?

15

void semWait(semaphore s) { while (test_and_set(lock)) { } s.count--; if (s.count < 0) { place P in s.queue; block P; } lock = 0;}

T&S: busy-wait during critical section Sem.: busy-wait just during semWait, semSignal:

very short operations!Copyright ©: University of Illinois CS 241 Staff

Page 16: Semaphores OS Basics

Mutual Exclusion Using Semaphores

semaphore s = 1; Pi {

while(1) { semWait(s); /* Critical Section */semSignal(s);/* remainder */

}}

16Copyright ©: University of Illinois CS 241 Staff

Page 17: Semaphores OS Basics

Value of Semaphore

lock

Queue A

semWait(lock)

0

1

semWait(lock)

B

-1semSignal(lock)

0

semSignal(lock)

1

Process Process Critical Region

Normal Execution

Blocked onsemaphore lock

B

17Copyright ©: University of Illinois CS 241 Staff

Page 18: Semaphores OS Basics

Semaphore Example 1

semaphore s = 2; Pi {

while(1) { semWait(s); /* CS */semSignal(s);/* remainder

*/}

}

What happens?

When might this be desirable?

18Copyright ©: University of Illinois CS 241 Staff

Page 19: Semaphores OS Basics

Semaphore Example 1

semaphore s = 2; Pi {

while(1) { semWait(s); /* CS */semSignal(s);/* remainder

*/}

}

What happens?

When might this be desirable?

19Copyright ©: University of Illinois CS 241 Staff

s = 2 1× 0× -1×

Page 20: Semaphores OS Basics

Semaphore Example 1

semaphore s = 2; Pi {

while(1) { semWait(s); /* CS */semSignal(s);/* remainder

*/}

}

What happens? Allows up to 2

processes to enter CS When might this be

desirable? Need up to 2 processes

inside CS e.g., limit number of

processes reading a var Be careful not to violate

mutual exclusion inside CS!

20Copyright ©: University of Illinois CS 241 Staff

Page 21: Semaphores OS Basics

Semaphore Example 2

semaphore s = 0; Pi {

while(1) { semWait(s); /* CS */semSignal(s);/* remainder

*/}

}

What happens?

When might this be desirable?

21Copyright ©: University of Illinois CS 241 Staff

Page 22: Semaphores OS Basics

Semaphore Example 2

semaphore s = 0; Pi {

while(1) { semWait(s); /* CS */semSignal(s);/* remainder

*/}

}

What happens?

When might this be desirable?

22Copyright ©: University of Illinois CS 241 Staff

s = 0 -1× -2× -3×

Page 23: Semaphores OS Basics

Semaphore Example 2

semaphore s = 0; Pi {

while(1) { semWait(s); /* CS */semSignal(s);/* remainder

*/}

}

What happens? No one can enter CS!

Ever! When might this be

desirable? Never!

23Copyright ©: University of Illinois CS 241 Staff

Page 24: Semaphores OS Basics

Semaphore Example 3

semaphore s = 0; P1 {

/* do some stuff */semWait(s); /* do some more stuff */

}

semaphore s; /* shared */P2 {

/* do some stuff */semSignal(s); /* do some more stuff */

} What happens?

When might this be desirable?

24Copyright ©: University of Illinois CS 241 Staff

Page 25: Semaphores OS Basics

Semaphore Example 3

semaphore s = 0; P1 {

/* do some stuff */semWait(s); /* do some more stuff */

}

semaphore s; /* shared */P2 {

/* do some stuff */semSignal(s); /* do some more stuff */

} What happens?

When might this be desirable?

25Copyright ©: University of Illinois CS 241 Staff

s = 1 0× 1×

Page 26: Semaphores OS Basics

Semaphore Example 3

semaphore s = 0; P1 {

/* do some stuff */semWait(s); /* do some more stuff */

}

semaphore s; /* shared */P2 {

/* do some stuff */semSignal(s); /* do some more stuff */

} What happens?

P1 waits until P2 signals if P2 signals first, P1 does not wait

When might this be desirable? Having a process/thread wait for another process/thread

26Copyright ©: University of Illinois CS 241 Staff

Page 27: Semaphores OS Basics

Semaphore Example 4

Process 1 executes:while(1) {

semWait(S);a;semSignal(Q);

}

Process 2 executes:while(1) {

semWait(Q);b;semSignal(S);

} Two processes

Two semaphores: S and Q Protect two critical variables ‘a’ and ‘b’.

What happens in the pseudocode if Semaphores S and Q are initialized to 1 (or 0)?

27Copyright ©: University of Illinois CS 241 Staff

Page 28: Semaphores OS Basics

Semaphore Example 4

Process 1 executes:while(1) {

semWait(S);a;semSignal(Q);

}

Process 2 executes:while(1) {

semWait(Q);b;semSignal(S);

}

28Copyright ©: University of Illinois CS 241 Staff

S = 0

Q = 0

-1×-1×

Page 29: Semaphores OS Basics

Semaphore Example 4

Process 1 executes:while(1) {

semWait(S);a;semSignal(Q);

}

Process 2 executes:while(1) {

semWait(Q);b;semSignal(S);

}

29Copyright ©: University of Illinois CS 241 Staff

S = 1

Q = 1

0×0×

1×1×

0×0×

Page 30: Semaphores OS Basics

Semaphore Example 4

Process 1 executes:while(1) {

semWait(S);a;semSignal(Q);

}

Process 2 executes:while(1) {

semWait(Q);b;semSignal(S);

}

30Copyright ©: University of Illinois CS 241 Staff

S = 1

Q = 1

0×0×

-1×1×

0×0×

Page 31: Semaphores OS Basics

Be careful!

Copyright ©: University of Illinois CS 241 Staff 31

semSignal(s);critical_section();semWait(s);

critical_section();semSignal(s);

semWait(s);critical_section();

semWait(s);critical_section();semWait(s);

semWait(s); semWait(s);critical_section();semSignal(s); semSignal(s);

1

2

3

4

5

Deadlock or Violation of Mutual Exclusion?

Page 32: Semaphores OS Basics

Be careful!

Copyright ©: University of Illinois CS 241 Staff 32

semSignal(s);critical_section();semWait(s);

critical_section();semSignal(s);

semWait(s);critical_section();

semWait(s);critical_section();semWait(s);

Mutual exclusion violation

Mutual exclusion violation

Possible deadlock

Certain deadlock!

semWait(s); semWait(s);critical_section();semSignal(s); semSignal(s);

Deadlock again!

1

2

3

4

5

Page 33: Semaphores OS Basics

POSIX Semaphores

Named Semaphores Provides synchronization between unrelated process and

related process as well as between threads Kernel persistence System-wide and limited in number Uses sem_open

Unnamed Semaphores Provides synchronization between threads and between

related processes Thread-shared or process-shared Uses sem_init

33Copyright ©: University of Illinois CS 241 Staff

Page 34: Semaphores OS Basics

POSIX Semaphores

Data type Semaphore is a variable of type sem_t

Include <semaphore.h> Atomic Operations

int sem_init(sem_t *sem, int pshared, unsigned value);

int sem_destroy(sem_t *sem);int sem_post(sem_t *sem);int sem_trywait(sem_t *sem);int sem_wait(sem_t *sem);

34Copyright ©: University of Illinois CS 241 Staff

Page 35: Semaphores OS Basics

Unnamed Semaphores

#include <semaphore.h>int sem_init(sem_t *sem, int pshared, unsigned value); Initialize an unnamed semaphore Returns

0 on success -1 on failure, sets errno

Parameters sem:

Target semaphore pshared:

0: only threads of the creating process can use the semaphore Non-0: other processes can use the semaphore

value: Initial value of the semaphore

You cannot make a copy of a semaphore variable!!!

35Copyright ©: University of Illinois CS 241 Staff

Page 36: Semaphores OS Basics

Sharing Semaphores

Sharing semaphores between threads within a process is easy, use pshared==0 Forking a process creates copies of any

semaphore it has… sem_t semaphores are not shared across processes

A non-zero pshared allows any process that can access the semaphore to use it Places the semaphore in the global (OS)

environment

36Copyright ©: University of Illinois CS 241 Staff

Page 37: Semaphores OS Basics

sem_init can fail

On failure sem_init returns -1 and sets errno

sem_t semA;

if (sem_init(&semA, 0, 1) == -1) perror(“Failed to initialize semaphore semA”);

Value > sem_value_maxResources exhaustedInsufficient privileges

EINVALENOSPCEPERM

causeerrno

37Copyright ©: University of Illinois CS 241 Staff

Page 38: Semaphores OS Basics

Semaphore Operations

#include <semaphore.h>int sem_destroy(sem_t *sem); Destroy an semaphore Returns

0 on success -1 on failure, sets errno

Parameters sem:

Target semaphore Notes

Can destroy a sem_t only once Destroying a destroyed semaphore gives undefined results Destroying a semaphore on which a thread is blocked gives undefined results

38Copyright ©: University of Illinois CS 241 Staff

Page 39: Semaphores OS Basics

Semaphore Operations

#include <semaphore.h>int sem_post(sem_t *sem); Unlock a semaphore Returns

0 on success -1 on failure, sets errno (== EINVAL if semaphore doesn’t exist)

Parameters sem:

Target semaphore sem > 0: no threads were blocked on this semaphore, the semaphore value is

incremented sem == 0: one blocked thread will be allowed to run

Notes sem_post() is reentrant with respect to signals and may be invoked from a signal-

catching function

39Copyright ©: University of Illinois CS 241 Staff

Page 40: Semaphores OS Basics

Semaphore Operations

#include <semaphore.h>int sem_wait(sem_t *sem); Lock a semaphore

Blocks if semaphore value is zero Returns

0 on success -1 on failure, sets errno (== EINTR if interrupted by a signal)

Parameters sem:

Target semaphore sem > 0: thread acquires lock sem == 0: thread blocks

40Copyright ©: University of Illinois CS 241 Staff

Page 41: Semaphores OS Basics

Semaphore Operations

#include <semaphore.h>int sem_trywait(sem_t *sem); Test a semaphore’s current condition

Does not block Returns

0 on success -1 on failure, sets errno (== AGAIN if semaphore already locked)

Parameters sem:

Target semaphore sem > 0: thread acquires lock sem == 0: thread returns

41Copyright ©: University of Illinois CS 241 Staff

Page 42: Semaphores OS Basics

Example: bank balance

Want shared variable balance to be protected by semaphore when used in: decshared – a function

that decrements the current value of balance

incshared – a function that increments the balance variable.

Copyright ©: University of Illinois CS 241 Staff 42

Page 43: Semaphores OS Basics

Example: bank balance

int decshared() { while (sem_wait(&balance_sem) == -1) if (errno != EINTR) return -1; balance--; return sem_post(&balance_sem);}

int incshared() { while (sem_wait(&balance_sem) == -1) if (errno != EINTR) return -1; balance++; return sem_post(&balance_sem); }

Copyright ©: University of Illinois CS 241 Staff 43

Page 44: Semaphores OS Basics

Summary

Semaphores Semaphore implementation POSIX Semaphore Programming with semaphores

Next time: solving real problems with semaphores & more

44Copyright ©: University of Illinois CS 241 Staff