diff --git a/BarlasChpt3Ex12/CMakeLists.txt b/BarlasChpt3Ex12/CMakeLists.txt new file mode 100644 index 0000000..3a7a3d4 --- /dev/null +++ b/BarlasChpt3Ex12/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.14) + +project(BarlasChpt3Ex12 LANGUAGES CXX) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core) + +add_executable(BarlasChpt3Ex12 + main.cpp +) +target_link_libraries(BarlasChpt3Ex12 Qt${QT_VERSION_MAJOR}::Core) + +include(GNUInstallDirs) +install(TARGETS BarlasChpt3Ex12 + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/BarlasChpt3Ex12/main.cpp b/BarlasChpt3Ex12/main.cpp new file mode 100644 index 0000000..099cd9f --- /dev/null +++ b/BarlasChpt3Ex12/main.cpp @@ -0,0 +1,86 @@ +#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: + printer(QSemaphore* lockBC, QSemaphore* lockC){ + this->lockBC = lockBC; + this->lockC = lockC; + } + + void printA(){ + this->lockBC->release(1); + std::cout << "A\n"; + } + + void printB(){ + if(this->lockBC->tryAcquire(1)){ + if(this->lockC->available() == 0){ + this->lockC->release(1); + } + std::cout << "B\n"; + } + } + + void printC(){ + if(this->lockBC->tryAcquire(1)){ + if(this->lockC->tryAcquire(1)){ + std::cout << "C\n"; + }else{ + this->lockBC->release(1); + } + } + } +}; + +class worker : public QThread{ +private: + QSemaphore* lockBC; + QSemaphore* lockC; + +public: + worker(QSemaphore* lockBC, QSemaphore* lockC){ + this->lockBC = lockBC; + this->lockC = lockC; + } + + void run(){ + printer print = printer(this->lockBC, this->lockC); + print.printA(); + print.printB(); + print.printC(); + } +}; + + +int main(int argc, char *argv[]) +{ + QSemaphore lockC(1); + QSemaphore lockBC(0); + + int N = 3; + worker *workers[N]; + for(int i = 0; i < N; i++){ + workers[i] = new worker(&lockBC, &lockC); + workers[i]->run(); + } + + return 0; +}