#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. */ struct IPrintable { ~IPrintable() = default; virtual auto print() const -> void = 0; }; class PrintA : public IPrintable { private: QSemaphore &lockBC_; public: explicit PrintA(QSemaphore &lockBc) : lockBC_(lockBc) {} auto print() const -> void override { this->lockBC_.release(1); std::cout << "A"; } }; class PrintB : public IPrintable { private: QSemaphore &lockBC_; QSemaphore &lockC_; public: explicit PrintB(QSemaphore &lockBc, QSemaphore &lockC) : lockBC_(lockBc), lockC_(lockC) {} auto print() const -> void override { if (this->lockBC_.tryAcquire(1)) { if (this->lockC_.available() == 0) { this->lockC_.release(1); } std::cout << "B"; } } }; class PrintC : public IPrintable { private: QSemaphore &lockBC_; QSemaphore &lockC_; public: explicit PrintC(QSemaphore &lockBc, QSemaphore &lockC) : lockBC_(lockBc), lockC_(lockC) {} auto print() const -> void override { if (this->lockBC_.tryAcquire(1)) { if (this->lockC_.tryAcquire(1)) { std::cout << "C"; } else { this->lockBC_.release(1); } } } }; template class Worker : public QThread { private: std::unique_ptr printer_; public: Worker(QString tname, Argts &... args) : printer_(std::make_unique(args...)) {}; protected: void run() { while (true) { printer_->print(); std::cout.flush(); sleep(1); } } }; int main(int argc, char *argv[]) { //QCoreApplication app(argc, argv); QSemaphore lockC(1); QSemaphore lockBC(0); Worker t1("Thread 1", lockBC); Worker t2("Thread 1", lockBC, lockC); Worker t3("Thread 1", lockBC, lockC); t1.start(); t2.start(); t3.start(); t1.wait(); t2.wait(); t3.wait(); //return app.exec(); return 0; }