Operating System
Assignment: 3
SP22-BCS-136
1.Implementing a Mutex Lock:
#include <mutex>
#include <thread>
#include <iostream>
using namespace std;
mutex mtx;
void accessSharedResource(int threadId)
lock_guard<mutex> lock(mtx);
cout << "Thread " << threadId << " acquired the lock." << endl;
this_thread::sleep_for(chrono::milliseconds(100));
cout << "Thread " << threadId << " releasing the lock." << endl;
}
int main()
thread t1(accessSharedResource, 1);
thread t2(accessSharedResource, 2);
thread t3(accessSharedResource, 3);
t1.join();
t2.join();
t3.join();
return 0;
output:
1. Semaphore Implementation:
#include <condition_variable>
#include <atomic>
#include <mutex>
#include <thread>
#include <iostream>
using namespace std;
mutex mtx;
condition_variable cv;
atomic<int> count;
const int MAX_COUNT = 3;
void accessSharedResource(int threadId)
unique_lock<mutex> lock(mtx);
cv.wait(lock, []
{ return count.load() < MAX_COUNT; });
count.fetch_add(1);
cout << "Thread " << threadId << " acquired the semaphore." << endl;
this_thread::sleep_for(chrono::milliseconds(100));
cout << "Thread " << threadId << " releasing the semaphore." << endl;
lock.unlock();
cv.notify_one();
int main()
count.store(0);
thread t1(accessSharedResource, 1);
thread t2(accessSharedResource, 2);
thread t3(accessSharedResource, 3);
thread t4(accessSharedResource, 4);
thread t5(accessSharedResource, 5);
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
return 0;
output:
2. Peterson's Solution Implementation:
#include <iostream>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <mutex>
#include <thread>
#include <sys/wait.h>
const int PROCESS_COUNT = 2;
struct SharedMemory
{
std::mutex mtx;
int turn;
bool flag[PROCESS_COUNT];
SharedMemory() : turn(0), flag{false, false} {}
};
const int SHARED_MEMORY_SIZE = sizeof(struct SharedMemory);
void enterCriticalSection(struct SharedMemory *shm, int processId)
{
shm->flag[processId] = true;
shm->turn = processId;
while (shm->turn == processId && shm->flag[1 - processId])
;
}
void leaveCriticalSection(struct SharedMemory *shm, int processId)
{
shm->flag[processId] = false;
}
void process(int processId)
{
int fd = shm_open("/my_shared_memory", O_RDWR | O_CREAT, 0666);
ftruncate(fd, SHARED_MEMORY_SIZE);
struct SharedMemory *shm = static_cast<struct SharedMemory
*>(mmap(NULL, SHARED_MEMORY_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0));
close(fd);
for (int i = 0; i < 10; i++)
{
enterCriticalSection(shm, processId);
std::cout << "Process " << processId << " entered the critical section."
<< std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Process " << processId << " left the critical section." <<
std::endl;
leaveCriticalSection(shm, processId);
}
munmap(shm, SHARED_MEMORY_SIZE);
}
int main()
{
pid_t pids[PROCESS_COUNT];
for (int i = 0; i < PROCESS_COUNT; i++)
{
pids[i] = fork();
if (pids[i] == 0)
{
process(i);
return 0;
}
else if (pids[i] < 0)
{
std::cerr << "Error in fork." << std::endl;
return 1;
}
}
for (int i = 0; i < PROCESS_COUNT; i++)
{
waitpid(pids[i], NULL, 0);
}
return 0;
}
output:
3. Producer-Consumer Problem with Mutex:
#include <iostream>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <chrono>
using namespace std;
const int BUFFER_SIZE = 5;
queue<int> sharedBuffer;
mutex mtx;
condition_variable cvProducer, cvConsumer;
bool finishedProducing = false;
void producer(int id)
for (int i = 0; i < 10; i++)
unique_lock<mutex> lock(mtx);
cvProducer.wait(lock, []
{ return sharedBuffer.size() < BUFFER_SIZE; });
int item = i;
sharedBuffer.push(item);
cout << "Producer " << id << " produced item " << item << endl;
cvConsumer.notify_one();
lock.unlock();
this_thread::sleep_for(chrono::milliseconds(100));
finishedProducing = true;
void consumer(int id)
while (!finishedProducing || !sharedBuffer.empty())
unique_lock<mutex> lock(mtx);
cvConsumer.wait(lock, []
{ return !sharedBuffer.empty(); });
int item = sharedBuffer.front();
sharedBuffer.pop();
cout << "Consumer " << id << " consumed item " << item << endl;
cvProducer.notify_one();
lock.unlock();
this_thread::sleep_for(chrono::milliseconds(100));
int main()
thread producer1(producer, 1);
thread producer2(producer, 2);
thread consumer1(consumer, 1);
thread consumer2(consumer, 2);
producer1.join();
producer2.join();
consumer1.join();
consumer2.join();
return 0;
output:
4. Reader-Writer Problem with Semaphores:
#include <iostream>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <chrono>
#include <semaphore.h>
const int MAX_READERS = 5;
const int MAX_WRITERS = 2;
sem_t rw_mutex, wr_mutex;
sem_t readers_mutex;
int readers = 0;
void reader(int id)
{
sem_wait(&readers_mutex);
readers++;
if (readers == 1)
sem_wait(&wr_mutex);
sem_post(&readers_mutex);
std::cout << "Reader " << id << " started reading." << std::endl;
// simulate reading
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Reader " << id << " finished reading." << std::endl;
sem_wait(&readers_mutex);
readers--;
if (readers == 0)
{
sem_post(&wr_mutex);
sem_post(&readers_mutex);
void writer(int id)
sem_wait(&wr_mutex);
std::cout << "Writer " << id << " started writing." << std::endl;
// simulate writing
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::cout << "Writer " << id << " finished writing." << std::endl;
sem_post(&wr_mutex);
}
int main()
sem_init(&rw_mutex, 0, 1);
sem_init(&wr_mutex, 0, 1);
sem_init(&readers_mutex, 0, 1);
std::thread reader1(reader, 1);
std::thread reader2(reader, 2);
std::thread reader3(reader, 3);
std::thread reader4(reader, 4);
std::thread reader5(reader, 5);
std::thread writer1(writer, 1);
std::thread writer2(writer, 2);
reader1.join();
reader2.join();
reader3.join();
reader4.join();
reader5.join();
writer1.join();
writer2.join();
sem_destroy(&rw_mutex);
sem_destroy(&wr_mutex);
sem_destroy(&readers_mutex);
return 0;
output: