/*************************************************************************** * * 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(); }