Download presentation
Presentation is loading. Please wait.
1
Process Synchronization
Synchronization involves the orderly sharing of system resources by processes. We can think of this intersection as a system resource that is shared by two processes: the car process and the train process One process is active at a time – No conflict Both processes are active – Conflict. Consider a machine with a single printer: Depending upon whether the printer is already being used by another process or not, the operating system must decide whether: to grant the printing request (if the printer is free), or to deny the request and classify the process as a waiting process until the printer becomes available.
2
What is wrong without synchronization ?
Unsynchronized Threads Sharing Memory
3
What is the solution ?
4
Mutexes One way to implement mutually exclusive access in computers is to use a flag (MUTEX ) that can be tested and set to either 0 or 1. Because both the test and set actions occur without interruption, this operation is indivisible and cannot be interrupted by another process which is running on the machine. By placing test-and-set operations around the critical section of a program, programmers can guarantee mutually exclusive access to the critical resource.
5
Mutexes Thread 1 Thread 2 Lock Have lock Lock Don’t Have lock
atomic Thread 2 Test &Set Mutex atomic Test &Set 1 Mutex Mutex=0 Lock Have lock Cr sect 1 M=N M=M+1 N=M Mutex=0 Lock Don’t Have lock Have lock Cr sect M=N M=M+1 N=M atomic Don’t Have lock Unlock Mutex=1 atomic Unlock Mutex=1
6
Mutexes or Binary Semaphore Example
The pictures below illustrate three processes sharing one critical resource. In order to access the critical section of their code, the processes must wait until the semaphore Mutex (Mutual exclusion) is one. When this happens, the process uses the test-and-set operation to change the value of Mutex to zero and then it executes its critical section (light color). Upon exiting the critical section, the process set the value of Mutex back to one to allow other processes to access the critical resource.
7
Busy waiting Atomic Operations Lock acquire Lock release
Wait lock to acquire Lock release Problems - Busy Waiting Disadvantage of the implementation given here is that it requires busy waiting, waist of CPU time while the other thread can use it. Advantage - no context switch is required when a process must wait on a lock. Lock holding expected to be short – spinlock is good (m-processor) Lock holding expected to be long – sleeping is good (m-program) If the Critical section is too long Problem - Busy Waiting before the lock acquired (Spinlock). Resolution - use semaphores They go to Sleep (Waiting queue) if they wait the lock to acquire.
8
Simple Semaphore for producer consumer
Mutex Mutex Go to Sleep Go to Sleep Lock_Acquire() 1 Lock_Acquire() 1 Mutex=0 Mutex=0 Critical Section Critical Section Mutually Exclusive Run M=N M=M+1 N=M Enqueue(item) Mutually Exclusive Run M=N M=M+1 N=M item = Dequeue() Mutex=1 Mutex=1 Lock_Release() Lock_Release() Represent the flowchart by functions to use them in more comfortable way
9
Wait and Signal Producer(item) { Lock_Acquire(); // Wait Enqueue(item); Lock_Release(); // Signal } Consumer() { Lock_Acquire(); // Wait item = Dequeue(); Lock_Release(); // Signal return item; }
10
Semaphores are a kind of generalized lock
Definition: a Semaphore has a non-negative integer value and supports the following two operations: P(): an atomic operation that waits for semaphore to become positive, then decrements it by 1 Think of this as the wait() operation V(): an atomic operation that increments the semaphore by 1, waking up a waiting P, if any Think of this as the signal() operation Note that P() stands for “proberen” (to test) and V() stands for “verhogen” (to increment) in Dutch
11
Mutual Exclusion on semaphores
(initial value = 1) Also called “Binary Semaphore”. Can be used for mutual exclusion: semaphore = 1; semaphore.P(); // -1 // Critical section goes here semaphore.V(); // +1
12
Semaphores language - Proberen and Verhogen
Producer(item) { Lock_Acquire(); Enqueue(item); Lock_Release(); } Consumer() { Lock_Acquire(); item = Dequeue(); Lock_Release(); return item; } Semaphore mutex = 1; // No one uses queue now Producer(item) { mutex.P(); // Wait until lock acquired,-1 Enqueue(item); mutex.V(); // Release lock and signal, +1 } Consumer() { mutex.P(); // Wait until lock acquired,-1 item = Dequeue(); mutex.V(); // Release lock and signal, +1 return item; }
13
Process Synchronization
Counting Semaphore Example for Bounded Buffer Problem
14
Semaphore usage for producer consumer
Producer needs to wait if queue is full (scheduling constraint) Consumer needs to wait if queue is empty (scheduling constraint) Only one thread can manipulate buffer queue at a time (mutual exclusion) out in
15
Full Solution to Bounded Buffer
Semaphore fullBuffers = 0; // Initially, no item Semaphore emptyBuffers = numBuffers; // Initially, num empty slots Semaphore mutex = 1; // No one using queue Producer(item) { emptyBuffers.P(); // Wait until space mutex.P(); // Wait until nobody uses qu. Enqueue(item); mutex.V(); fullBuffers.V(); // Tell consumers there is // more item } Consumer() { fullBuffers.P(); // Check if there’s an item mutex.P(); // Wait until nobody uses qu. item = Dequeue(); mutex.V(); emptyBuffers.V(); // tell producer need more return item; }
16
Semaphores conclusion
Complex to use Change the places of 2 P()s Deadlock ? If the Critical Section initiates some I/O then that thread goes to sleep with the acquired lock. All the other threads should wait the lock until this I/O is finished. Producer(item) { emptyBuffers.P(); // Wait until space mutex.P(); // Wait until buffer free Enqueue(item); mutex.V(); fullBuffers.V(); // Tell consumers there is // more item } Solution: Use Condition Variables and Monitors suggested by different languages. They hide the complex parts of semaphores and allow the threads to sleep in critical section but with releasing the lock.
17
POSIX Semaphores DESCRIPTION #include <semaphore.h>
This manual page documents POSIX b semaphores, not to be confused with SystemV semaphores as described in ipc(5), semctl(2) and semop(2). #include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value); - sem_init initializes the semaphore object pointed to by sem. int sem_wait(sem_t * sem); (suspends thread until sem is non 0, then atomically decreases the sem count) int sem_trywait(sem_t * sem); - non-blocking variant of sem_wait int sem_post(sem_t * sem); - atomically increases the count of the semaphore pointed to by sem int sem_getvalue(sem_t * sem, int * sval); - stores in the location pointed to by sval the current count of the semaphore sem. int sem_destroy(sem_t * sem); - destroys a semaphore object
18
WinAPI Semaphores case WM_CREATE:
case WM_CREATE: hSema= CreateSemaphore (NULL, 1, 1, "mysem"); - global variable . . . case WM_LBUTTONDOWN: CreateThread (NULL,0, (LPTHREAD_START_ROUTINE) MyThread1,(LPVOID)hwnd, 0, &Tid1); (LPTHREAD_START_ROUTINE) MyThread2,(LPVOID)hwnd, 0, &Tid2); // DWORD MyThread1 (LPVOID param) { if (WaitForSingleObject (hSema, 10000) == WAIT_TIMEOUT) { MessageBox ((HWND) param, "Thread 1 - Timeout", "Semaphore error", MB_OK); return 0; } for (i=0; i<10; i++) { } ReleaseSemaphore (hSema, 1, NULL);
19
Deadlock Sometimes, a waiting process is never again able to change state, because the resources it has requested are held by other waiting processes. This situation is called a deadlock. In a deadlock, processes never finish executing, and system resources are tied up, preventing other jobs from starting.
20
Deadlock conditions In order for deadlock to be possible, the following four conditions must be present in the computer: 1. Mutual exclusion: only one process may use a resource at a time 2. Hold-and-wait: a process may hold allocated resources while awaiting assignment of others 3. No preemption: no resource can be forcibly removed from a process holding it 4. Circular wait:
21
Resource-Allocation Graph
System Model A set of Processes P1, P2, . . ., Pn Resource types R1, R2, . . ., Rm CPU cycles, memory space, I/O devices Each resource type Ri has Wi instances. Each thread utilizes a resource as follows: Request() / Use() / Release() Resource-Allocation Graph: V is partitioned into two types: P = {P1, P2, …, Pn}, the set of processes in the system. R = {R1, R2, …, Rm}, the set of resource types in system request edge – directed edge P1 Rj assignment edge – directed edge Rj Pi
22
Resource-Allocation Graph examples
Resource-allocation graph with a deadlock Resource-allocation graph with a cycle but no deadlock.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.