diff --git a/task3/main-ab.cpp b/task3/main-ab.cpp new file mode 100644 index 0000000..4fc8575 --- /dev/null +++ b/task3/main-ab.cpp @@ -0,0 +1,83 @@ +#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_; + + QString name_; + +public: + explicit Printer(QSemaphore &lockBC, QSemaphore &lockC, QString name) : lockBC_(lockBC), lockC_(lockC), + name_(name) {}; + + void printA() { + this->lockBC_.release(1); + std::cout << name_.toStdString() << " A\n"; + } + + void printB() { + if (this->lockBC_.tryAcquire(1, 10000)) { + if (this->lockC_.available() == 0) { + this->lockC_.release(1); + } + std::cout << name_.toStdString() << " B\n"; + } + } + + void printC() { + if (this->lockBC_.tryAcquire(1, 10000)) { + if (this->lockC_.tryAcquire(1, 10000)) { + std::cout << name_.toStdString() << " C\n"; + } else { + this->lockBC_.release(1); + } + } + } +}; + +class Worker : public QThread { +private: + Printer printer_; + +public: + Worker(QSemaphore &lockBC, QSemaphore &lockC, QString tname) : printer_(lockBC, lockC, tname) {}; + +protected: + void run() { + printer_.printA(); + printer_.printB(); + printer_.printC(); + } +}; + + +int main(int argc, char *argv[]) { + QCoreApplication app(argc, 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, QString("Thread %1").arg(i)); + workers[i]->start(); + } + + return app.exec(); +}