LCB2022057 DivyanshGautam assignmentOS
LCB2022057 DivyanshGautam assignmentOS
Q. 1 Two processes, Process A and Process B, are accessing a shared variable counter. You want to ensure data
consistency by synchronising their access.
Part 1: Semaphores for Iteration Control
You are given a program with two processes (A and B) that iterate and print values. Modify the program to implement
synchronization using a semaphore.
Process A should not start iteration i before Process B finishes iteration i-1.
Explain the changes you made and how they achieve synchronization.
Part 2: Semaphores for Critical Sections
Modify the program again to simulate a scenario where both processes modify the shared variable counter.
Identify the critical section for each process (the code segment that modifies the counter).
Use a semaphore to ensure mutual exclusion between the two processes when accessing their critical sections.
Explain the placement of the semaphore operations (wait and signal) within the code to achieve synchronization.
Q.2 Write a C or JAVA program for thread synchronisation using counting semaphores. Application to
demonstrate:producer-consumer problem with counting semaphores and mutex.
LCB2022057
DIVYANSH GAUTAM
#include <iostream> // Process B function
#include <thread> void process_b() {
Q1: #include <mutex> for (int i = 0; i < MAX_ITERATIONS; ++i) {
#include <semaphore.h> // Wait for Process A to finish iteration i
sem_wait(&iteration_semaphore);
// Define the maximum number of
iterations // Critical section for Process B
#define MAX_ITERATIONS 5 std::lock_guard<std::mutex> lock(counter_mutex);
counter--; // Decrement the counter
// Shared variables std::cout << "Process B - Counter: " << counter << std::endl;
int counter = 0;
sem_t iteration_semaphore; // Semaphore // Signal Process A to start its next iteration
for iteration control sem_post(&iteration_semaphore);
sem_t critical_section_semaphore; // }
Semaphore for critical sections }
std::mutex counter_mutex; // Mutex for
mutual exclusion int main() {
// Initialize semaphores
// Process A function sem_init(&iteration_semaphore, 0, 1); // Initialize with value 1
void process_a() { sem_init(&critical_section_semaphore, 0, 1); // Initialize with value 1
for (int i = 0; i < MAX_ITERATIONS; ++i) {
// Wait for Process B to finish iteration // Create threads for Process A and Process B
i-1 std::thread thread_a(process_a);
sem_wait(&iteration_semaphore); std::thread thread_b(process_b);
return 0;
}
In this program:
We have two threads: producer and consumer.
The producer produces items and puts them into a shared buffer.
The consumer consumes items from the buffer.
We use two semaphores (empty and full) to keep track of empty and filled slots
in the buffer, respectively.
We use a mutex (mutex) to ensure mutual exclusion when accessing the shared
buffer.
The producer waits for an empty slot in the buffer before producing an item and
signals that a slot in the buffer is filled after producing an item.
The consumer waits for a filled slot in the buffer before consuming an item and
signals that a slot in the buffer is empty after consuming an item.
This ensures that the producer and consumer synchronize their operations
properly, preventing issues such as buffer overflow or underflow.