Readers-Writers
#include<bits/stdc++.h>
using namespace std;
int mutx = 0;
void wait_mutx() {
while (mutx) {
// wait
}
mutx = 1;
}
void signal_mutx() {
mutx = 0;
}
int rw_mutx = 0;
void wait_rw_mutx() {
while (rw_mutx) {
// wait
}
rw_mutx = 1;
}
void signal_rw_mutx() {
rw_mutx = 0;
}
// action = 0 -> leave
// action = 1 -> enter
void writer(int action) {
if (action) {
wait_rw_mutx();
cout << "Writer is writing..." << endl;
sleep(1); // Simulate writing time
} else {
signal_rw_mutx();
cout << "Writer has finished writing." << endl;
sleep(1); // Simulate time after writing
}
}
int readers_count = 0;
void reader(int action) {
if (action) {
wait_mutx();
readers_count++;
if (readers_count == 1) {
wait_rw_mutx();
}
signal_mutx();
cout << "Reader is reading..." << endl;
sleep(1); // Simulate reading time
} else {
wait_mutx();
readers_count--;
if (readers_count == 0) {
signal_rw_mutx();
}
signal_mutx();
cout << "Reader has finished reading." << endl;
sleep(1); // Simulate time after reading
}
}
int main() {
thread t1(writer, 1);
thread t2(reader, 1);
thread t3(reader, 1);
thread t4(reader, 0);
thread t5(writer, 0);
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
return 0;
}
Monitor
Simple implementation
#include<bits/stdc++.h>
using namespace std;
enum state { THINKING, HUNGRY, EATING };
class Philosopher {
public:
state s[5];
Philosopher() {
for(int i = 0; i < 5; i++) {
s[i] = THINKING;
}
}
void test(int i);
void pickUp(int i);
void putDown(int i);
};
void Philosopher::test(int i) {
if (s[i] == HUNGRY && s[(i + 4)%5] != EATING && s[(i + 1) % 5] != EATING) {
s[i] = EATING;
}
cout << "Philosopher " << i << " is " << (s[i] == EATING ? "EATING" : (s[i] == HUNGRY ? "HUNGRY" : "THINKING")) << endl;
}
void Philosopher::pickUp(int i) {
s[i] = HUNGRY;
if (s[i] != EATING) {
test(i);
}
cout << "Philosopher " << i << " is " << (s[i] == EATING ? "EATING" : (s[i] == HUNGRY ? "HUNGRY" : "THINKING")) << endl;
cout << "------------------------------------------" << endl;
}
void Philosopher::putDown(int i) {
s[i] = THINKING;
test((i + 4) % 5);
test((i + 1) % 5);
}
int main() {
Philosopher p;
p.pickUp(0);
p.pickUp(1);
p.putDown(0);
p.pickUp(2);
return 0;
}
With spinlock
#include<bits/stdc++.h>
using namespace std;
enum state { THINKING, HUNGRY, EATING };
class Philosopher {
public:
state s[5];
Philosopher() {
for(int i = 0; i < 5; i++) {
s[i] = THINKING;
}
}
void test(int i);
void pickUp(int i);
void putDown(int i);
};
void Philosopher::test(int i) {
if (s[i] == HUNGRY && s[(i + 4)%5] != EATING && s[(i + 1) % 5] != EATING) {
s[i] = EATING;
}
}
void Philosopher::pickUp(int i) {
s[i] = HUNGRY;
while (s[i] != EATING) {
test(i);
}
printf("Philosopher %d is %s\n", i, (s[i] == EATING) ? "EATING" : "HUNGRY");
}
void Philosopher::putDown(int i) {
s[i] = THINKING;
}
int main() {
Philosopher p;
thread t[5];
t[0] = thread(&Philosopher::pickUp, &p, 0);
t[1] = thread(&Philosopher::pickUp, &p, 1);
t[2] = thread(&Philosopher::putDown, &p, 0);
t[3] = thread(&Philosopher::putDown, &p, 1);
t[0].join();
t[1].join();
t[2].join();
t[3].join();
return 0;
}
Without spinlock
#include<bits/stdc++.h>
using namespace std;
enum state { THINKING, HUNGRY, EATING };
class Philosopher {
public:
state s[5];
Philosopher() {
for(int i = 0; i < 5; i++) {
s[i] = THINKING;
}
}
void test(int i);
void pickUp(int i);
void putDown(int i);
};
void Philosopher::test(int i) {
if (s[i] == HUNGRY && s[(i + 4)%5] != EATING && s[(i + 1) % 5] != EATING) {
s[i] = EATING;
printf("Philosopher %d is %s\n", i, (s[i] == EATING) ? "EATING" : "HUNGRY");
pickUp(i);
}
}
void Philosopher::pickUp(int i) {
if (s[i] != EATING) {
s[i] = HUNGRY;
test(i);
}
}
void Philosopher::putDown(int i) {
s[i] = THINKING;
test((i + 4) % 5);
test((i + 1) % 5);
}
int main() {
Philosopher p;
thread t[5];
t[0] = thread(&Philosopher::pickUp, &p, 0);
t[1] = thread(&Philosopher::pickUp, &p, 1);
t[2] = thread(&Philosopher::putDown, &p, 0);
t[3] = thread(&Philosopher::putDown, &p, 1);
t[0].join();
t[1].join();
t[2].join();
t[3].join();
return 0;
}