From 71fad746b33887b00e5ad2c50f8d8c83880aff74 Mon Sep 17 00:00:00 2001 From: Robin Dietzel Date: Sat, 2 Dec 2023 14:34:06 +0100 Subject: [PATCH] Fix threads --- CMakeLists.txt | 3 +- CMakePresets.json | 18 +++++++-- task3/CMakeLists.txt | 8 ++++ task3/main.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 task3/CMakeLists.txt create mode 100644 task3/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 40b601c..3a6e44c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,4 +25,5 @@ endif () add_subdirectory(third-party/fmt) # Include CMakeLists files from subdirs for specific tasks -add_subdirectory(task1) \ No newline at end of file +add_subdirectory(task1) +add_subdirectory(task3) \ No newline at end of file diff --git a/CMakePresets.json b/CMakePresets.json index 7a6500e..d0243b9 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -7,14 +7,24 @@ }, "configurePresets": [ { - "name": "task1@release", - "displayName": "Task1 Release build", - "description": "Builds the targets of task1 as release", + "name": "task@release", + "displayName": "Task Release build", + "description": "Builds the target as release", "generator": "Ninja", - "binaryDir": "${sourceDir}/.out/task1-release", + "binaryDir": "${sourceDir}/.out/task-release", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } + }, + { + "name": "task@debug", + "displayName": "Task Debug build", + "description": "Builds the target as debug", + "generator": "Ninja", + "binaryDir": "${sourceDir}/.out/task-debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } } ] } \ No newline at end of file diff --git a/task3/CMakeLists.txt b/task3/CMakeLists.txt new file mode 100644 index 0000000..4081dd2 --- /dev/null +++ b/task3/CMakeLists.txt @@ -0,0 +1,8 @@ + +find_package(Qt6 COMPONENTS Core REQUIRED) + +add_executable(task3-chpt3ex12) +target_sources(task3-chpt3ex12 PRIVATE + main.cpp) +target_link_libraries(task3-chpt3ex12 PRIVATE +Qt6::Core) \ No newline at end of file diff --git a/task3/main.cpp b/task3/main.cpp new file mode 100644 index 0000000..f6ec304 --- /dev/null +++ b/task3/main.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include + +/* + * Barlas Chpt 3 Ex 12: + Create three threads, each printing out the letters A, B, and C. + The printing must adhere to these rules: + • The total number of Bs and Cs that have been output at any + point in the output string cannot exceed the total number + of As that have been output at that point. + • After a C has been output, another C cannot be output until + one or more Bs have been output. + Use semaphores to solve the problem. +*/ + +class Printer { +private: + QSemaphore &lockBC; + QSemaphore &lockC; + +public: + explicit Printer(QSemaphore &lockBC, QSemaphore &lockC) : lockBC(lockBC), lockC(lockC) {}; + + void printA() { + this->lockBC.release(1); + std::cout << "A\n"; + } + + void printB() { + if (this->lockBC.tryAcquire(1, 10000)) { + if (this->lockC.available() == 0) { + this->lockC.release(1); + } + std::cout << "B\n"; + } + } + + void printC() { + if (this->lockBC.tryAcquire(1, 10000)) { + if (this->lockC.tryAcquire(1, 10000)) { + std::cout << "C\n"; + } else { + this->lockBC.release(1); + } + } + } +}; + +class Worker : public QThread { +private: + QSemaphore &lockBC; + QSemaphore &lockC; + +public: + Worker(QSemaphore &lockBC, QSemaphore &lockC) : lockBC(lockBC), lockC(lockC) {}; + +protected: + void run() { + Printer print = Printer(this->lockBC, this->lockC); + print.printA(); + print.printB(); + print.printC(); + } +}; + + +int main(int argc, char *argv[]) { + QCoreApplication app(argc, argv); + QSemaphore lockC(1); + QSemaphore lockBC(0); + + Worker trd1(lockBC, lockC); + Worker trd2(lockBC, lockC); + Worker trd3(lockBC, lockC); + + trd1.start(); + trd2.start(); + trd3.start(); + +// int N = 3; +// Worker *workers[N]; +// for (int i = 0; i < N; i++) { +// workers[i] = new Worker(lockBC, lockC); +// workers[i]->run(); +// } + + return app.exec(); +}