diff --git a/task3/CMakeLists.txt b/task3/CMakeLists.txt index 05558ae..2791049 100644 --- a/task3/CMakeLists.txt +++ b/task3/CMakeLists.txt @@ -6,4 +6,12 @@ target_sources(task3-chpt3ex12-rd PRIVATE main-rd.cpp) target_link_libraries(task3-chpt3ex12-rd PRIVATE + Qt6::Core) + +add_executable(task3-bonus-rd) + +target_sources(task3-bonus-rd PRIVATE + main-bonus-task-rd.cpp) + +target_link_libraries(task3-bonus-rd PRIVATE Qt6::Core) \ No newline at end of file diff --git a/task3/main-bonus-task-rd.cpp b/task3/main-bonus-task-rd.cpp new file mode 100644 index 0000000..5d80335 --- /dev/null +++ b/task3/main-bonus-task-rd.cpp @@ -0,0 +1,119 @@ +/*************************************************************************** + * + * main.cpp: Code to solve Barlas Exersice 3-12. + * + * Version 0.5 by Hartmut Weber: Just a template. 3-11 not solved. + * 1.0 by ............. + * + * Statemet of Version 1.0 Authorship: + * ................ + * + **************************************************************************/ +#include +#include +#include +#include +#include +#include + +using namespace std; + +#define CHAR_COUNT_MAX 500 +#define TIME_FACTOR 2 + +int charCount = 0; +QSemaphore semCharCount(1); +QRandomGenerator *randg = QRandomGenerator::global(); + +QSemaphore lockBC_(0); +QSemaphore lockC_(0); + +class AThread : public QThread { +private: + int ID; +public: + AThread(int i) : ID(i) {} + + void run() { + while (charCount < CHAR_COUNT_MAX) { + lockBC_.release(1); + printf("A"); + fflush(stdout); + semCharCount.acquire(); + charCount++; + semCharCount.release(); + msleep((randg->generate() % 3 + 1) * TIME_FACTOR); + } + return; + } +}; + +class BThread : public QThread { +private: + int ID; +public: + BThread(int i) : ID(i) {} + + void run() { + while (charCount < CHAR_COUNT_MAX) { + if (lockBC_.tryAcquire(1)) { + if (lockC_.available() == 0) { + lockC_.release(1); + } + printf("B"); + fflush(stdout); + semCharCount.acquire(); + charCount++; + semCharCount.release(); + }; + msleep((randg->generate() % 3 + 1) * TIME_FACTOR); + } + return; + } +}; + +class CThread : public QThread { +private: + int ID; +public: + CThread(int i) : ID(i) {} + + void run() { + while (charCount < CHAR_COUNT_MAX) { + if (lockC_.tryAcquire(1) && lockBC_.tryAcquire(1)) { + printf("C"); + fflush(stdout); + semCharCount.acquire(); + charCount++; + semCharCount.release(); + } + msleep((randg->generate() % 3 + 1) * TIME_FACTOR); + } + return; + } +}; + +int main(int argc, char *argv[]) { + QCoreApplication a(argc, argv); + + printf("START\n\n"); + fflush(stdout); + AThread *pTa = new AThread(1); + BThread *pTb = new BThread(2); + CThread *pTc = new CThread(3); + + pTa->start(); + pTb->start(); + pTc->start(); + + pTa->wait(); + pTb->wait(); + pTc->wait(); + printf("\n\n"); + fflush(stdout); + + // Let event loop do at least one turn. (https:/stackoverflow.com/questions/4180394) + QTimer::singleShot(0, &a, &QCoreApplication::quit); // Let event loop do at least one turn. + + return a.exec(); +}