Operating Systems Synchronization Part 2 Semaphores Semaphores Used

  • Slides: 30
Download presentation
Operating Systems Synchronization, Part 2 Semaphores

Operating Systems Synchronization, Part 2 Semaphores

Semaphores • Used to control access to a common resource by multiple processes in

Semaphores • Used to control access to a common resource by multiple processes in a concurrent system – A record of how many units of a particular resource are available – Two operations (up/down) to adjust that record safely • Semaphores which allow an arbitrary resource count are called counting semaphores • Binary semaphores (mutex) are restricted to the semaphores values 0 and 1

Counting semaphore Init(i) S=i down(S) [the ‘p’ operation] down(S) up(S) [the `v’ operation] If

Counting semaphore Init(i) S=i down(S) [the ‘p’ operation] down(S) up(S) [the `v’ operation] If (S≤ 0) If (there are blocked processes) wake-up one of them Else S++ the process is blocked. It will resume execution only after it is woken-up Else S-- • Semaphore’s interface doesn’t enforce the implementation of starvation freedom • All operations are ATOMIC! That is, up(s) is more than just s: =s+1 • There is no way to access the semaphore’s internal value. Any attempt to access it is a mistake. • Always remember to initialize the semaphore 3

Negative-valued semaphore down(S) up(S) [the `v’ operation] S-If (S<0) the process is blocked. It

Negative-valued semaphore down(S) up(S) [the `v’ operation] S-If (S<0) the process is blocked. It will resume execution only after it is woken-up S++ If (there are blocked processes) wake-up one of them NOTE: If S is negative, there are |S| blocked processes 4

Counting Semaphores (Barz) Create a counting semaphore, S, by using binary semaphores S. value=init_value

Counting Semaphores (Barz) Create a counting semaphore, S, by using binary semaphores S. value=init_value Variables ? binary-semaphore: S 1=1, ? S 2=min(1, init_value), ? down(S) down(S 2); down(S 1); S. value--; if (S. value>0) then up(S 2); up(S 1); up(S): down(S 1); S. value++; if (S. value == 1) then up(S 2); up(S 1); 5

Question 1 Consider the following code snippets run by two processes, P and Q:

Question 1 Consider the following code snippets run by two processes, P and Q: Shared memory n=5; sqr=0; Process P loop. P: if (n==0) goto end. P; n=n-1; goto loop. P; end. P: print(sqr) Process Q loop. Q: sqr = sqr + 2*n +1; goto loop. Q; Add the minimal number of semaphores, initialize them and place them in the code snippets, so the result of the calculation will be correct (52=25). 6

Question 1 Note that we can break 25 in more than one way: •

Question 1 Note that we can break 25 in more than one way: • 25=11+9+5=[(2*5+1)+(2*4+1)+(2*2+1)] • 25=9+7+5+3+1=[(2*4+1)+(2*3+1)+(2*2+1)+(2*1+1)+(0+1)] Shared memory n=5; sqr=0; sem. A=1; sem. B=0; Process P loop. P: if (n==0) goto end. P; down(sem. A); n=n-1; up(sem. B); goto loop. P; end. P: down(sem. A); print(sqr) Process Q loop. Q: down(sem. B); sqr = sqr + 2*n +1; up(sem. A); goto loop. Q; 7

Question 2 (2007 Moed A) The following constraint graph is a DAG that defines

Question 2 (2007 Moed A) The following constraint graph is a DAG that defines a partial order over code lines. Each vertex is associated with a single line of code in a possible program. A directed edge e(u, v) is used to represent the precedence constraint: code line u must be completed prior to the beginning of code line v. For example, code line S 1 should be completed before S 2, S 5 or S 8 are executed, while S 6 can only be executed after both S 2 and S 5 were completed. 8 8

Question 2 a The following code is executed by two processes, A and B.

Question 2 a The following code is executed by two processes, A and B. Process A S 1 S 5 S 8 S 9 S 7 Process B S 2 S 3 S 6 S 4

Question 2 a Use two counting semaphores with properly initialized two counting semaphores values

Question 2 a Use two counting semaphores with properly initialized two counting semaphores values so that in every execution of A and B the execution order of code lines will be consistent with the constraint graph defined above. That is, add up and down operations within A and B’s up down code lines so that no precedence constraint is violated. You may assume that in every execution both A and B run their code only once. Note: Partial scoring will be given to solutions using more than two semaphores. 10 10

Question 2 a Semaphores: sem. A=0, sem. B=0 Process A S 1 Sem. B.

Question 2 a Semaphores: sem. A=0, sem. B=0 Process A S 1 Sem. B. up S 5 Sem. B. up S 8 S 9 Sem. A. down S 7 Sem. B. up 11 Process B Sem. B. down S 2 S 3 Sem. B. down S 6 Sem. A. up Sem. B. down S 4 11

Question 2 b Give a concise but accurate explanation why a single semaphore is

Question 2 b Give a concise but accurate explanation why a single semaphore is insufficient for maintaining consistency of the above constraint graph and the two processes. 12 12

Question 2 b A single semaphore is insufficient because there are constraints which require

Question 2 b A single semaphore is insufficient because there are constraints which require that A waits until B completes one of its lines and vice versa. In such a state, having A signaling B and immediately waiting for it on the same semaphore will result in either a deadlock or a breaking of one of its constraints. 13 13

Question 3 – Producer Consumer Problem #define N semaphore 100 mutex = 1; empty

Question 3 – Producer Consumer Problem #define N semaphore 100 mutex = 1; empty = N; full = 0; void producer(void) { producer int item; while(TRUE) { produce_item(&item); down(&empty); down(&mutex); down enter_item(item); up(&mutex); up up(&full); up } } /* Buffer size */ /* access control to critical section */ /* counts empty buffer slots */ /* full slots */ /* generate something. . . */ /* decrement count of empty */ /* enter critical section */ /* insert into buffer */ /* leave critical section */ /* increment count of full slots */ 14

Question 3 – Producer Consumer Problem void consumer(void){ int item; } while(TRUE){ down(&full); down(&mutex);

Question 3 – Producer Consumer Problem void consumer(void){ int item; } while(TRUE){ down(&full); down(&mutex); down remove_item(&item); up(&mutex); up up(&empty); up consume_item(item); } /* decrement count of full */ /* enter critical section */ /* take item from buffer */ /* leave critical section */ /* update count of empty */ /* do something. . . */ 15

Question 3 1. The red lines of the following code were swapped. How will

Question 3 1. The red lines of the following code were swapped. How will this affect the algorithm? void producer(void) { producer int item; while(TRUE) { produce_item(&item); down(&empty); down(&mutex); down up(&mutex); enter_item(item); up(&full); up } } /* generate something. . . */ /* decrement count of empty */ /* enter critical section */ /* leave critical section */ /* insert into buffer */ /* increment count of full slots */ No mutual exclusion! 16

Question 3 2. What will happen now? void producer(void) { producer int item; while(TRUE)

Question 3 2. What will happen now? void producer(void) { producer int item; while(TRUE) { produce_item(&item); down(&empty); down(&mutex); down enter_item(item); up(&full); up(&mutex); } } /* generate something. . . */ /* decrement count of empty */ /* enter critical section */ /* insert into buffer */ /* increment count of full slots */ /* leave critical section */ No problems… 17

Question 3 3. And now? void consumer(void){ int item; } while(TRUE){ down(&mutex); /* enter

Question 3 3. And now? void consumer(void){ int item; } while(TRUE){ down(&mutex); /* enter critical section */ down(&full); /* decrement count of full */ remove_item(&item); /* take item from buffer */ up(&mutex); /* leave critical section */ up up(&empty); /* update count of empty */ up consume_item(item); /* do something. . . */ } Deadlock! 18

Question 4 (Moed B 2010) An unfair semaphore is a semaphore which does not

Question 4 (Moed B 2010) An unfair semaphore is a semaphore which does not guarantee that the wakeup order of processes is similar to their falling asleep order. It does, however, provide the following simple guarantee: if there are sleeping processes on the semaphore while an up operation is invoked, up then one of these processes will be woken up (not necessarily the first amongst the waiting processes to do a down). down

Question 4 Now you are required to implement a starvation free mutual exclusion algorithm

Question 4 Now you are required to implement a starvation free mutual exclusion algorithm for three processes using 3 unfair counting semaphores: R, S and T, initialized to 1. You are not allowed to use any other variable but these semaphores. Add your code and complete the entry and exit section of each process. Briefly explain why your code satisfies both mutual exclusion and starvation freedom.

Question 4 unfair counting semaphores: R, S and T initialized to 1 P 1’s

Question 4 unfair counting semaphores: R, S and T initialized to 1 P 1’s code: entry: P 2’s code: entry: P 3’s code: entry: Critical_section() exit:

Question 4 unfair counting semaphores: R, S and T initialized to 1 P 1’s

Question 4 unfair counting semaphores: R, S and T initialized to 1 P 1’s code: entry: down (S) down (R) P 2’s code: entry: down (R) down (T) P 3’s code: entry: down (S) down (T) Critical_section() exit: up(R) up(S) Critical_section() exit: up(T) up(R) Critical_section() exit: up(T) up (S)

Question 4 Mutual exclusion: Any process wishing to enter its critical section must successfully

Question 4 Mutual exclusion: Any process wishing to enter its critical section must successfully complete two ‘down’ operations on two distinct semaphores. Since any process competes over one different “successful down” with each of the other processes, only a single process may successfully enter the critical section at any given moment.

Question 4 Starvation freedom: We first note that there is no starvation problem when

Question 4 Starvation freedom: We first note that there is no starvation problem when using an unfair semaphore with 2 processes (convince yourselves!). Since entrance to the critical section requires passing semaphores which are only shared in pairs no starvation problems will occur.

Question 4, supplement unfair counting semaphores: R, S and T initialized to 1 P

Question 4, supplement unfair counting semaphores: R, S and T initialized to 1 P 1’s code: entry: down (S) down (R) P 2’s code: entry: down (R) down (T) P 3’s code: entry: down (T) down (S) Critical_section() exit: up(R) up(S) Critical_section() exit: up(T) up(R) Critical_section() exit: up(S) up (T) Will this solution work? Deadlock!

Question 5 int waitval[N] (all are initialized to 0) int v = 0 semaphore

Question 5 int waitval[N] (all are initialized to 0) int v = 0 semaphore wait[N] (all are initialized to 0) Shared variables semaphore mutex (initialized to 1) Advance(E) down(mutex); E. v++; for (i = 0; i < N; i++) if (waitval[i] == E. v) up(wait[i]); up(mutex); Await(E, v) boolean wait = false; down(mutex) if (v > E. v) { wait = true; waitval[My. Id] = v; } up(mutex); if (wait) down(wait[My. Id]); Read(E) return E. v; 27

Question 5 b ( מסמאפורים counting semaphore) למדתם כי אין זה פשוט לממש סמאפור

Question 5 b ( מסמאפורים counting semaphore) למדתם כי אין זה פשוט לממש סמאפור כללי להלן קטע קוד המכיל מימוש של. מסתבר כי גם הכוון ההפוך אינו פשוט. בינאריים . ( ומרגיסטרים counting semaphores) סמאפור בינארי מסמאפורים כלליים Counting semaphore mutex=1 Counting semaphore b=0 register v=0, register waiting=0 procedure down( ) { mutex. down( ) if (v == 1){ v=0 mutex. up( )} else { waiting=waiting+1 mutex. up( ) b. down( ) }} procedure up( ){ mutex. down( ) if (waiting > 0){ waiting=waiting-1 b. up( )} else if (v == 0) v=1 mutex. up( ) } 28

Question 5 b תארו במדויק תסריט בו מספר תהליכים מבצעים פעולות על המימוש לעיל

Question 5 b תארו במדויק תסריט בו מספר תהליכים מבצעים פעולות על המימוש לעיל ובו . המימוש אינו מקיים סמאנטיקה זו Process p 1 does down and stops prior to b. down Process p 2 does down and stops prior to b. down Process p 3 does up and finishes the operation (b == 1) Process p 4 does up and finishes the operation (b == 2) Process p 5 does down and finishes the operation (b == 1) Process p 6 does down and finishes the operation (b == 0) התסריט אינו אפשרי כאשר משתמשים בסמפור בינארי מכיוון שלא יכול להיות מצב . ושניהם יצליחו DOWN שבו שני תהליכים יעשו 30