Synchronization and Semaphores

Slides:



Advertisements
Similar presentations
1 Chapter 5 Concurrency: Mutual Exclusion and Synchronization Principals of Concurrency Mutual Exclusion: Hardware Support Semaphores Readers/Writers Problem.
Advertisements

Ch. 7 Process Synchronization (1/2) I Background F Producer - Consumer process :  Compiler, Assembler, Loader, · · · · · · F Bounded buffer.
Chapter 6: Process Synchronization
Background Concurrent access to shared data can lead to inconsistencies Maintaining data consistency among cooperating processes is critical What is wrong.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition, Chapter 6: Process Synchronization.
Process Synchronization. Module 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores.
CS444/CS544 Operating Systems Synchronization 2/21/2006 Prof. Searleman
Informationsteknologi Wednesday, September 26, 2007 Computer Systems/Operating Systems - Class 91 Today’s class Mutual exclusion and synchronization 
Day 14 Concurrency. Software approaches Programs must be written such that they ensure mutual exclusion. Petersons and Dekkers (Appendix B)
Enforcing Mutual Exclusion, Semaphores. Four different approaches Hardware support Disable interrupts Special instructions Software-defined approaches.
Chapter 5 Concurrency: Mutual Exclusion and Synchronization
5.6 Semaphores Semaphores –Software construct that can be used to enforce mutual exclusion –Contains a protected variable Can be accessed only via wait.
5.6 Semaphores Semaphores –Software construct that can be used to enforce mutual exclusion –Contains a protected variable Can be accessed only via wait.
Chapter 6: Process Synchronization. Outline Background Critical-Section Problem Peterson’s Solution Synchronization Hardware Semaphores Classic Problems.
Chapter 6: Process Synchronization. 6.2 Silberschatz, Galvin and Gagne ©2005 Operating System Concepts – 7 th Edition, Feb 8, 2005 Objectives Understand.
5.6.2 Thread Synchronization with Semaphores Semaphores can be used to notify other threads that events have occurred –Producer-consumer relationship Producer.
Jonathan Walpole Computer Science Portland State University
Synchronization Solutions
Instructor: Umar KalimNUST Institute of Information Technology Operating Systems Process Synchronization.
Operating Systems CSE 411 CPU Management Oct Lecture 13 Instructor: Bhuvan Urgaonkar.
Concurrency, Mutual Exclusion and Synchronization.
6.3 Peterson’s Solution The two processes share two variables: Int turn; Boolean flag[2] The variable turn indicates whose turn it is to enter the critical.
Copyright ©: University of Illinois CS 241 Staff1 Synchronization and Semaphores.
Copyright ©: Nahrstedt, Angrave, Abdelzaher1 Semaphore and Mutex Operations.
Midterm 1 – Wednesday, June 4  Chapters 1-3: understand material as it relates to concepts covered  Chapter 4 - Processes: 4.1 Process Concept 4.2 Process.
1 Chapter 6: Process Synchronization Background The Critical-Section Problem Peterson’s Solution Special Machine Instructions for Synchronization Semaphores.
Silberschatz, Galvin and Gagne  Operating System Concepts Chapter 7: Process Synchronization Background The Critical-Section Problem Synchronization.
Chap 6 Synchronization. Background Concurrent access to shared data may result in data inconsistency Maintaining data consistency requires mechanisms.
Silberschatz, Galvin and Gagne ©2013 Operating System Concepts Essentials – 9 th Edition Chapter 5: Process Synchronization.
Chapter 6 – Process Synchronisation (Pgs 225 – 267)
Synchronizing Threads with Semaphores
CS252: Systems Programming Ninghui Li Based on Slides by Prof. Gustavo Rodriguez-Rivera Topic 11: Thread-safe Data Structures, Semaphores.
Chapter 6: Process Synchronization. 6.2 Silberschatz, Galvin and Gagne ©2005 Operating System Concepts Module 6: Process Synchronization Background The.
Background Concurrent access to shared data may result in data inconsistency Maintaining data consistency requires mechanisms to ensure the orderly execution.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
Computer Architecture and Operating Systems CS 3230: Operating System Section Lecture OS-5 Process Synchronization Department of Computer Science and Software.
Synchronization CSCI 3753 Operating Systems Spring 2005 Prof. Rick Han.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Chapter 6: Process Synchronization.
Mutual Exclusion -- Addendum. Mutual Exclusion in Critical Sections.
Chapter 6 Synchronization Dr. Yingwu Zhu. The Problem with Concurrent Execution Concurrent processes (& threads) often access shared data and resources.
Web Server Architecture Client Main Thread for(j=0;j
© Janice Regan, CMPT 300, May CMPT 300 Introduction to Operating Systems Mutual Exclusion Mutexes, Semaphores.
Process Synchronization. Concurrency Definition: Two or more processes execute concurrently when they execute different activities on different devices.
OS Winter’03 Concurrency. OS Winter’03 Bakery algorithm of Lamport  Critical section algorithm for any n>1  Each time a process is requesting an entry.
Synchronization and Semaphores
Semaphores Synchronization tool (provided by the OS) that does not require busy waiting. Logically, a semaphore S is an integer variable that, apart from.
Chapter 6: Process Synchronization
Process Synchronization
Chapter 5: Process Synchronization
Process Synchronization: Semaphores
Chapter 5: Process Synchronization – Part 3
PARALLEL PROGRAM CHALLENGES
Background on the need for Synchronization
Process Synchronization
Chapter 5: Process Synchronization
Chapter 5: Process Synchronization
Topic 6 (Textbook - Chapter 5) Process Synchronization
Semaphore Originally called P() and V() wait (S) { while S <= 0
Module 7a: Classic Synchronization
Concurrency: Mutual Exclusion and Synchronization
Lecture 2 Part 2 Process Synchronization
Critical section problem
Synchronization Primitives – Semaphore and Mutex
CSE 153 Design of Operating Systems Winter 19
CSE 153 Design of Operating Systems Winter 2019
CS333 Intro to Operating Systems
Synchronization.
Chapter 6: Synchronization Tools
Synchronization.
Process/Thread Synchronization (Part 2)
Presentation transcript:

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

Copyright ©: University of Illinois CS 241 Staff 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 interrupts While(true) { /* disable interrupts */ /* critical section */ /* enable interrupts */ /* remainder */ } What’s the problem with this solution? Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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) Copyright ©: University of Illinois CS 241 Staff

Test and Set Instruction boolean Test_And_Set(boolean* lock) atomic { boolean initial; initial = *lock; *lock = true; return initial; } atomic = executed in a single shot without any interruption Note: this is more accurate than the textbook version Copyright ©: University of Illinois CS 241 Staff

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); } What's the problem? Copyright ©: University of Illinois CS 241 Staff

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. Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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 Copyright ©: University of Illinois CS 241 Staff

Semaphores vs. Test_and_Set semaphore s = 1; Pi { while(1) { semWait(s); /* Critical Section */ semSignal(s); /* remainder */ } lock = 0; Pi { while(1) { while(Test_And_Set(lock)); /* Critical Section */ lock =0; /* remainder */ } Avoid busy waiting by suspending Block if s == False Wakeup on signal (s = True) Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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

Copyright ©: University of Illinois CS 241 Staff Inside a Semaphore Add a waiting queue Multiple process waiting on s Wakeup one of the blocked processes upon getting a signal Semaphore data structure typedef struct { int count; queueType queue; /* queue for procs. waiting on s */ } SEMAPHORE; Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Binary Semaphores typedef struct bsemaphore { enum {0,1} value; queueType queue; } BSEMAPHORE; void semWaitB(bsemaphore s) { if (s.value == 1) s.value = 0; else { place P in s.queue; block P; } void semSignalB (bsemaphore s) { if (s.queue is empty()) s.value = 1; else { remove P from s.queue; place P on ready list; } Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff General Semaphore typedef struct { int count; queueType queue; } SEMAPHORE; void semWait(semaphore s) { s.count--; if (s.count < 0) { place P in s.queue; block P; } void semSignal(semaphore s) { s.count++; if (s.count ≤ 0) { remove P from s.queue; place P on ready list; } Copyright ©: University of Illinois CS 241 Staff

Making the operations atomic Isn’t this exactly what semaphores were trying to solve? Are we stuck?! Solution: resort to test-and-set typedef struct { boolean lock; int count; queueType queue; } SEMAPHORE; void semWait(semaphore s) { s.count--; if (s.count < 0) { place P in s.queue; block P; } 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

Making the operations atomic Busy-waiting again! Then how are semaphores better than just using test_and_set? 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

Mutual Exclusion Using Semaphores semaphore s = 1; Pi { while(1) { semWait(s); /* Critical Section */ semSignal(s); /* remainder */ } Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Process Process Critical Region Value of Semaphore lock Queue B A Normal Execution Blocked on semaphore lock 1 semWait(lock) semWait(lock) B -1 semSignal(lock) semSignal(lock) 1 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Semaphore Example 1 semaphore s = 2; Pi { while(1) { semWait(s); /* CS */ semSignal(s); /* remainder */ } What happens? When might this be desirable? Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Semaphore Example 1 semaphore s = 2; Pi { while(1) { semWait(s); /* CS */ semSignal(s); /* remainder */ } What happens? When might this be desirable? × × × s = 2 1 -1 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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! Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Semaphore Example 2 semaphore s = 0; Pi { while(1) { semWait(s); /* CS */ semSignal(s); /* remainder */ } What happens? When might this be desirable? Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Semaphore Example 2 semaphore s = 0; Pi { while(1) { semWait(s); /* CS */ semSignal(s); /* remainder */ } What happens? When might this be desirable? × × × s = 0 -1 -2 -3 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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! Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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? Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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? × × s = 1 1 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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)? Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Semaphore Example 4 Process 1 executes: while(1) { semWait(S); a; semSignal(Q); } Process 2 executes: while(1) { semWait(Q); b; semSignal(S); } × S = 0 -1 × Q = 0 -1 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Semaphore Example 4 Process 1 executes: while(1) { semWait(S); a; semSignal(Q); } Process 2 executes: while(1) { semWait(Q); b; semSignal(S); } × × × S = 1 1 × × × Q = 1 1 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Semaphore Example 4 Process 1 executes: while(1) { semWait(S); a; semSignal(Q); } Process 2 executes: while(1) { semWait(Q); b; semSignal(S); } × × × × S = 1 -1 1 × × × Q = 1 1 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Be careful! Deadlock or Violation of Mutual Exclusion? semSignal(s); critical_section(); semWait(s); semWait(s); critical_section(); 1 4 semWait(s); critical_section(); semSignal(s); semWait(s); critical_section(); 5 2 critical_section(); semSignal(s); 3 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Be careful! Mutual exclusion violation Certain deadlock! semSignal(s); critical_section(); semWait(s); semWait(s); critical_section(); 1 4 Possible deadlock Deadlock again! semWait(s); critical_section(); semSignal(s); semWait(s); critical_section(); 5 2 Mutual exclusion violation critical_section(); semSignal(s); 3 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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); Copyright ©: University of Illinois CS 241 Staff

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!!! Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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_max Resources exhausted Insufficient privileges EINVAL ENOSPC EPERM cause errno Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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 Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff 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

Copyright ©: University of Illinois CS 241 Staff Example: bank balance int decshared() { while (sem_wait(&balance_sem) == -1) if (errno != EINTR) return -1; balance--; return sem_post(&balance_sem); } int incshared() { balance++; Copyright ©: University of Illinois CS 241 Staff

Copyright ©: University of Illinois CS 241 Staff Summary Semaphores Semaphore implementation POSIX Semaphore Programming with semaphores Next time: solving real problems with semaphores & more Copyright ©: University of Illinois CS 241 Staff