lab5, reader/writer problem
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
class ReaderWriter {
|
class ReaderWriter {
|
||||||
public:
|
public:
|
||||||
ReaderWriter(int numReaders, int numWriters, const std::string& filename);
|
ReaderWriter(int numReaders, int numWriters, std::string filename);
|
||||||
~ReaderWriter();
|
~ReaderWriter();
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
@@ -19,9 +19,10 @@ private:
|
|||||||
int numWriters;
|
int numWriters;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
|
|
||||||
sem_t resourceAccess;
|
sem_t resourceAccess{};
|
||||||
sem_t readCountAccess;
|
sem_t readCountAccess{};
|
||||||
int readCount;
|
int readCount;
|
||||||
|
int writeCount;
|
||||||
|
|
||||||
static void* reader(void* arg);
|
static void* reader(void* arg);
|
||||||
static void* writer(void* arg);
|
static void* writer(void* arg);
|
||||||
|
|||||||
26
main.cpp
26
main.cpp
@@ -6,6 +6,7 @@
|
|||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "producer.h"
|
#include "producer.h"
|
||||||
#include "consumer.h"
|
#include "consumer.h"
|
||||||
|
#include "reader_writer.h"
|
||||||
|
|
||||||
[[noreturn]] void runSignalHandler() {
|
[[noreturn]] void runSignalHandler() {
|
||||||
setupSignalHandlers();
|
setupSignalHandlers();
|
||||||
@@ -45,11 +46,24 @@ void runProducerConsumer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void runReaderWriter() {
|
||||||
|
int numReaders = 5;
|
||||||
|
int numWriters = 2;
|
||||||
|
std::string filename = "shared_resource.txt";
|
||||||
|
|
||||||
|
std::ofstream file(filename, std::ios::trunc);
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
ReaderWriter rw(numReaders, numWriters, filename);
|
||||||
|
rw.run();
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
while (true) {
|
while (true) {
|
||||||
std::cout << "=== Main Menu ===\n";
|
std::cout << "=== Main Menu ===\n";
|
||||||
std::cout << "1. Run Signal Handler Program\n";
|
std::cout << "1. Run Signal Handler\n";
|
||||||
std::cout << "2. Run Producer/Consumer Program\n";
|
std::cout << "2. Run Producer/Consumer\n";
|
||||||
|
std::cout << "3. Run Reader/Writer\n";
|
||||||
std::cout << "0. Exit\n";
|
std::cout << "0. Exit\n";
|
||||||
std::cout << "Enter your choice: ";
|
std::cout << "Enter your choice: ";
|
||||||
|
|
||||||
@@ -58,13 +72,17 @@ int main() {
|
|||||||
|
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case 1:
|
case 1:
|
||||||
std::cout << "Running Signal Handler Program...\n";
|
std::cout << "Running Signal Handler...\n";
|
||||||
runSignalHandler();
|
runSignalHandler();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
std::cout << "Running Producer/Consumer Program...\n";
|
std::cout << "Running Producer/Consumer...\n";
|
||||||
runProducerConsumer();
|
runProducerConsumer();
|
||||||
break;
|
break;
|
||||||
|
case 3:
|
||||||
|
std::cout << "Running Reader-Writer...\n";
|
||||||
|
runReaderWriter();
|
||||||
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
std::cout << "Exiting program. Goodbye!\n";
|
std::cout << "Exiting program. Goodbye!\n";
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -3,3 +3,100 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "reader_writer.h"
|
#include "reader_writer.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <utility>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
ReaderWriter::ReaderWriter(const int numReaders, const int numWriters, std::string filename)
|
||||||
|
: numReaders(numReaders), numWriters(numWriters), filename(std::move(filename)), readCount(0), writeCount(0) {
|
||||||
|
sem_init(&resourceAccess, 0, 1);
|
||||||
|
sem_init(&readCountAccess, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReaderWriter::~ReaderWriter() {
|
||||||
|
sem_destroy(&resourceAccess);
|
||||||
|
sem_destroy(&readCountAccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ReaderWriter::reader(void* arg) {
|
||||||
|
auto* rw = static_cast<ReaderWriter*>(arg);
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
sem_wait(&rw->readCountAccess);
|
||||||
|
rw->readCount++;
|
||||||
|
if (rw->readCount == 1) {
|
||||||
|
sem_wait(&rw->resourceAccess);
|
||||||
|
}
|
||||||
|
sem_post(&rw->readCountAccess);
|
||||||
|
|
||||||
|
if (std::ifstream file(rw->filename); file.is_open()) {
|
||||||
|
std::ostringstream output;
|
||||||
|
output << "Reader reading: ";
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
output << line << " ";
|
||||||
|
}
|
||||||
|
output << std::endl;
|
||||||
|
std::cout << output.str();
|
||||||
|
} else {
|
||||||
|
std::cerr << "Reader could not open file\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sem_wait(&rw->readCountAccess);
|
||||||
|
rw->readCount--;
|
||||||
|
if (rw->readCount == 0) {
|
||||||
|
sem_post(&rw->resourceAccess);
|
||||||
|
}
|
||||||
|
sem_post(&rw->readCountAccess);
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void* ReaderWriter::writer(void* arg) {
|
||||||
|
auto* rw = static_cast<ReaderWriter*>(arg);
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
sem_wait(&rw->resourceAccess);
|
||||||
|
|
||||||
|
std::ofstream file(rw->filename, std::ios::app);
|
||||||
|
if (file.is_open()) {
|
||||||
|
file << rw->writeCount << "\n";
|
||||||
|
std::cout << "Writer writing: " << rw->writeCount << std::endl;
|
||||||
|
rw->writeCount++;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Writer could not open file\n";
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
sem_post(&rw->resourceAccess);
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReaderWriter::run() {
|
||||||
|
std::vector<pthread_t> readerThreads(numReaders);
|
||||||
|
std::vector<pthread_t> writerThreads(numWriters);
|
||||||
|
|
||||||
|
for (int i = 0; i < numReaders; ++i) {
|
||||||
|
pthread_create(&readerThreads[i], nullptr, reader, this);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < numWriters; ++i) {
|
||||||
|
pthread_create(&writerThreads[i], nullptr, writer, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& t : readerThreads) {
|
||||||
|
pthread_join(t, nullptr);
|
||||||
|
}
|
||||||
|
for (const auto& t : writerThreads) {
|
||||||
|
pthread_join(t, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user