From c0670991b17ae410ad76698720b068e18e95e46c Mon Sep 17 00:00:00 2001 From: Lumijiez Date: Sun, 8 Dec 2024 19:19:22 +0200 Subject: [PATCH] lab5, reader/writer problem --- include/reader_writer.h | 7 +-- main.cpp | 26 +++++++++-- src/reader_writer.cpp | 97 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 7 deletions(-) diff --git a/include/reader_writer.h b/include/reader_writer.h index 7b92969..9e7712e 100644 --- a/include/reader_writer.h +++ b/include/reader_writer.h @@ -10,7 +10,7 @@ class ReaderWriter { public: - ReaderWriter(int numReaders, int numWriters, const std::string& filename); + ReaderWriter(int numReaders, int numWriters, std::string filename); ~ReaderWriter(); void run(); @@ -19,9 +19,10 @@ private: int numWriters; std::string filename; - sem_t resourceAccess; - sem_t readCountAccess; + sem_t resourceAccess{}; + sem_t readCountAccess{}; int readCount; + int writeCount; static void* reader(void* arg); static void* writer(void* arg); diff --git a/main.cpp b/main.cpp index 69e5289..aff8b28 100644 --- a/main.cpp +++ b/main.cpp @@ -6,6 +6,7 @@ #include "buffer.h" #include "producer.h" #include "consumer.h" +#include "reader_writer.h" [[noreturn]] void runSignalHandler() { 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() { while (true) { std::cout << "=== Main Menu ===\n"; - std::cout << "1. Run Signal Handler Program\n"; - std::cout << "2. Run Producer/Consumer Program\n"; + std::cout << "1. Run Signal Handler\n"; + std::cout << "2. Run Producer/Consumer\n"; + std::cout << "3. Run Reader/Writer\n"; std::cout << "0. Exit\n"; std::cout << "Enter your choice: "; @@ -58,13 +72,17 @@ int main() { switch (choice) { case 1: - std::cout << "Running Signal Handler Program...\n"; + std::cout << "Running Signal Handler...\n"; runSignalHandler(); break; case 2: - std::cout << "Running Producer/Consumer Program...\n"; + std::cout << "Running Producer/Consumer...\n"; runProducerConsumer(); break; + case 3: + std::cout << "Running Reader-Writer...\n"; + runReaderWriter(); + break; case 0: std::cout << "Exiting program. Goodbye!\n"; return 0; diff --git a/src/reader_writer.cpp b/src/reader_writer.cpp index eb2e51f..ecf32fc 100644 --- a/src/reader_writer.cpp +++ b/src/reader_writer.cpp @@ -3,3 +3,100 @@ // #include "reader_writer.h" + +#include +#include +#include +#include +#include + +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(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(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 readerThreads(numReaders); + std::vector 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); + } +} \ No newline at end of file