This document discusses solutions to the critical section problem in concurrent programming. It describes the requirements of mutual exclusion, progress, and bounded waiting. Peterson's solution is presented as a classic software-based approach using flags. Hardware-based solutions using locks and semaphores are also discussed. Semaphores provide a higher-level abstraction than locks by allowing processes to block waiting for a condition. The producer-consumer problem and readers-writers problem are presented as examples requiring synchronization. Monitors provide mutual exclusion and condition variables within a high-level interface.
This document discusses solutions to the critical section problem in concurrent programming. It describes the requirements of mutual exclusion, progress, and bounded waiting. Peterson's solution is presented as a classic software-based approach using flags. Hardware-based solutions using locks and semaphores are also discussed. Semaphores provide a higher-level abstraction than locks by allowing processes to block waiting for a condition. The producer-consumer problem and readers-writers problem are presented as examples requiring synchronization. Monitors provide mutual exclusion and condition variables within a high-level interface.
This document discusses solutions to the critical section problem in concurrent programming. It describes the requirements of mutual exclusion, progress, and bounded waiting. Peterson's solution is presented as a classic software-based approach using flags. Hardware-based solutions using locks and semaphores are also discussed. Semaphores provide a higher-level abstraction than locks by allowing processes to block waiting for a condition. The producer-consumer problem and readers-writers problem are presented as examples requiring synchronization. Monitors provide mutual exclusion and condition variables within a high-level interface.
➢Each process has a segment of code, basic machine-language instructions, such as
called a critical section in which the process load and store. may be changing common variables, ➢There are no guarantees that Peterson's updating a table, writing a file, and so on. solution will work correctly on such ➢The important feature of the system is architectures. that, when one process is executing in its ➢We present the solution because it critical section, no other process is to be provides a good algorithmic description of allowed to execute in its critical section. solving the critical-section problem ➢That is, no two processes are executing in ➢It illustrates some of the complexities their critical sections at the same time. involved in designing software that Critical-Section Problem addresses the requirements of mutual It is to design a protocol that the processes exclusion, progress, and bounded waiting. can use to cooperate. Each process must ➢It is restricted to two processes that request permission to enter its critical alternate execution between their critical section. The section of code implementing sections and remainder sections this request is the entry section. The critical SYNCHRONIZATION HARDWARE section may be followed by an exit section. It can generally state that any solution to The remaining code is the remainder the critical-section problem requires a section. simple tool-a lock. Race conditions are 1.Mutual exclusion prevented by requiring that critical regions ➢If process Pi is executing in its critical be protected by locks. That is, a process section, then no other processes can be must acquire a lock before entering a critical executing in their critical sections. section; it releases the lock when it exits the 2.Progress. critical section. ➢If no process is executing in its critical Mutex Locks section and some processes wish to enter ➢Simplest tool s to solve the critical-section their critical sections, then only those problem is mutex lock. processes that are not executing in their ➢A process must acquire the lock before remainder sections can participate in entering a critical section; it releases the deciding which will enter its critical section lock when it exits the critical section. next, and this selection cannot be ➢The acquire()function acquires the lock, postponed indefinitely. and the release() function releases the lock 3 Bounded waiting. ➢A mutex lock has a boolean variable ➢There exists a bound, or limit, on the available whose value indicates if the lock is number of times that other processes are available or not. If the lock is available, a call allowed to enter their critical sections after to acquire() succeeds, and the lock is then a process has made a request to enter its considered unavailable. A process that critical section and before that request is attempts to acquire an unavailable lock is granted blocked until the lock is released. PETERSON’S SOLUTION ➢A classic software-based solution to the critical-section problem known as Peterson's solution. SEMAPHORE ➢the signal() semaphore operation can be The hardware-based solutions to the critical- defined as section problem presented are complicated signal(semaphore *S) { for application programmers to use. To S->value++; overcome this difficulty a synchronization if (S->value <= 0) { tool called a semaphore is used. A remove a process P from S->list; semaphore S is an integer variable that, wakeup(P); } apart from initialization, is accessed only Deadlocks and Starvation through two standard atomic operations: The implementation of a semaphore with a wait () and signal (). The wait () operation waiting queue may result in a situation was originally termed P (from the Dutch where two or more processes are waiting proberen, "to test"); signal() was originally indefinitely for an event that can be caused called V (from verhogen, "to increment"). only by one of the waiting processes. When The definition of wait () is as follows: such a state is reached, these processes are wait(S) said to be deadlocked { while S <= 0 Priority Inversion II busy waiting ➢Scheduling problem when lower-priority s--; } process holds a lock needed by higher- The definition of signal() is as follows: priority process signal(S) Monitors { S++; } ➢A high-level abstraction that provides a Semaphore Implementation convenient and effective mechanism for When a process executes the wait() process synchronization operation and finds that the semaphore ➢It is an ADT(Abstract data type) that value is not positive, it must wait. However, includes a set of programmer defined rather than engaging in busy waiting, the operations that are provided with mutual process can block itself. The block operation exclusion within the monitor. The monitor places a process into a waiting queue type also declares the variables whose associated with the semaphore, and the values define the state of an instance of that state of the process is switched to the type, along with the bodies of functions that waiting state. Then control is transferred to operate on those variables the CPU scheduler, which selects another { /* shared variable declarations */ process to execute. function P1(...) { ➢a semaphore can be defined as follows: ... typedef struct{ } int value; function P2(...) { struct process *list; ... } semaphore; } ➢The wait() semaphore operation can be ... defined as function Pn(...) { wait(semaphore *S) { ... S->value--; } if (S->value < 0) { initialization code (...) { add this process to S->list; ... block(); } } Syntax of a monitor }} ➢A function defined within a monitor can /* remove an item from buffer to access only those variables declared locally next_consumed */ ... within the monitor and its formal parameter signal(mutex); signal(empty); ... ➢The local variables of a monitor can be /* consume the item in next consumed */ ... accessed by only the local functions. ➢The } while (true); monitor construct ensures that only one Readers-Writers Problem process at a time is active within the ➢A data set is shared among a number of monitor. ➢A monitor consists of a mutex concurrent processes *Readers – only read (lock) object and condition variables. A the data set; they do not perform any condition variable is basically a container of updates *Writers – can both read and write threads that are waiting for a certain ➢Problem *allow multiple readers to read condition. Monitors provide a mechanism at the same time *Only one single writer can for threads to temporarily give up exclusive access the shared data at the same time access in order to wait for some condition to ➢To ensure that these difficulties do not be met, before regaining exclusive access arise, we require that the writers have and resuming their task exclusive access to the shared database Producer-Consumer Problem while writing to the database. This ➢The producer and consumer processes synchronization problem is referred this share the following data structures: ➢The readers–writers problem has several int n; variations, •The first readers–writers semaphore mutex = 1; problem requires that no reader be kept semaphore empty = n; waiting unless a writer has already obtained semaphore full = 0 permission to use the shared object. In ➢The pool consists of n buffers, each other words, no reader should wait for capable of holding one item. The mutex other readers to finish simply because a semaphore provides mutual exclusion for writer is waiting •The second readers – accesses to the buffer pool and is initialized writers problem requires that, once a writer to the value 1. The empty and full is ready, that writer perform its write as semaphores count the number of empty soon as possible. In other words, if a writer and full buffers. The semaphore empty is is waiting to access the object, no new initialized to the value n; the semaphore full readers may start reading is initialized to the value 0. The structure of a writer process do { wait(rw_mutex); ... ➢The producer producing full buffers for /* writing is performed */ ... the consumer or as the consumer producing signal(rw_mutex); } while (true); empty buffers for the producer. ➢The structure of a reader process ➢The structure of the producer process. do { wait(mutex); read_count++; do { ... if (read_count == 1) wait(rw_mutex); /* produce an item in next_produced */ ... signal(mutex); ... wait(empty); wait(mutex); ... /* reading is performed */ ... /* add next produced to the buffer */ ... wait(mutex); read count--; signal(mutex); signal(full); if (read_count == 0) signal(rw_mutex); } while (true); signal(mutex); } while (true); ➢The structure of the consumer process do { wait(full); wait(mutex); ...