-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
151 lines (133 loc) · 5.35 KB
/
main.cpp
File metadata and controls
151 lines (133 loc) · 5.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <iostream>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <fstream>
using namespace std;
// Synchronization variables
pthread_mutex_t mutex; // Protects read_count
pthread_mutex_t printLock; // Protects cout
sem_t wrt;
int read_count = 0;
int CYCLES = 3;
bool delayReaders = false; //Optional delay for reader (for TC3)
void* reader(void* arg) {
int id = *((int*)arg);
if (delayReaders) sleep(1); // Optional delay to let writer go first
for (int i = 0; i < CYCLES; ++i) {
// Entry section
pthread_mutex_lock(&mutex);
read_count++;
if (read_count == 1)
sem_wait(&wrt); // First reader blocks writers
pthread_mutex_unlock(&mutex);
// Reading section
pthread_mutex_lock(&printLock);
cout << "Reader " << id << " starts reading." << endl;
pthread_mutex_unlock(&printLock);
ifstream inFile("io_shared_file.txt"); // Read from the shared file
if (inFile.is_open()) {
string line;
while (getline(inFile, line)) {
pthread_mutex_lock(&printLock);
cout << "Reader " << id << " reads: " << line << endl;
pthread_mutex_unlock(&printLock);
}
inFile.close();
} else { // Error if file can't be opened
pthread_mutex_lock(&printLock);
cout << "Reader " << id << " could not open file." << endl;
pthread_mutex_unlock(&printLock);
}
pthread_mutex_lock(&printLock); // Finish reading
cout << "Reader " << id << " finishes reading." << endl;
pthread_mutex_unlock(&printLock);
// Exit section
pthread_mutex_lock(&mutex);
read_count--;
if (read_count == 0)
sem_post(&wrt); // Last reader unblocks writers
pthread_mutex_unlock(&mutex);
sleep(1); // Simulate delay between read cycles
}
return nullptr;
}
void* writer(void* arg) {
int id = *((int*)arg); // Get the writer's ID from the argument
for (int i = 0; i < CYCLES; ++i) {
pthread_mutex_lock(&printLock); // Show that the writer is waiting to get access
cout << "Writer " << id << " is waiting to write..." << endl;
pthread_mutex_unlock(&printLock);
sem_wait(&wrt); // Only one writer allowed at a time
pthread_mutex_lock(&printLock);
cout << "Writer " << id << " starts writing." << endl; // Critical section: start writing
pthread_mutex_unlock(&printLock);
// Open the file in append mode and write a line
ofstream outFile("io_shared_file.txt", ios::app);
if (outFile.is_open()) {
outFile << ", Writer " << id << " wrote at cycle " << (i + 1) << endl;
outFile.close();
} else {
pthread_mutex_lock(&printLock); // Done writing
cout << "Writer " << id << " could not write to file." << endl;
pthread_mutex_unlock(&printLock);
}
pthread_mutex_lock(&printLock);
cout << "Writer " << id << " finishes writing." << endl;
pthread_mutex_unlock(&printLock);
sem_post(&wrt); // Release the semaphore to let readers/writers continue
sleep(2); // Simulate time delay between writing cycles
}
return nullptr;
}
int main() {
int numReaders, numWriters;
// Init sync mechanisms
pthread_mutex_init(&mutex, nullptr); // For protecting read_count
pthread_mutex_init(&printLock, nullptr); // For clean printing
sem_init(&wrt, 0, 1); // Writer semaphore
// Display banner
pthread_mutex_lock(&printLock);
cout << "==================================================================\n";
cout << " Reader-Writer Synchronization\n";
cout << "==================================================================\n";
pthread_mutex_unlock(&printLock);
// User input
cout << "Enter number of reader threads: ";
cin >> numReaders;
cout << "Enter number of writer threads: ";
cin >> numWriters;
cout << "Enter number of cycles per thread: ";
cin >> CYCLES;
cout << "Delay readers? (1 = Yes, 0 = No): ";
int delayInput;
cin >> delayInput;
delayReaders = (delayInput == 1);
cout << "==================================================================\n";
// Thread creation
pthread_t readers[numReaders], writers[numWriters];
int readerIDs[numReaders], writerIDs[numWriters];
for (int i = 0; i < numReaders; ++i) { // Create reader threads
readerIDs[i] = i + 1;
pthread_create(&readers[i], nullptr, reader, &readerIDs[i]);
}
for (int i = 0; i < numWriters; ++i) {
writerIDs[i] = i + 1;
pthread_create(&writers[i], nullptr, writer, &writerIDs[i]);
}
// Thread join
for (int i = 0; i < numReaders; ++i)
pthread_join(readers[i], nullptr);
for (int i = 0; i < numWriters; ++i)
pthread_join(writers[i], nullptr);
pthread_mutex_lock(&printLock); // Final output
cout << "==================================================================\n";
cout << "Simulation complete. All reader and writer threads have finished\n";
cout << "==================================================================\n";
pthread_mutex_unlock(&printLock);
// Clean-up
pthread_mutex_destroy(&mutex);
pthread_mutex_destroy(&printLock);
sem_destroy(&wrt);
return 0;
}