aca-tasks/task3/main-bonus-task-rd.cpp

120 lines
3.0 KiB
C++
Raw Permalink Normal View History

2023-12-09 12:53:56 +00:00
/***************************************************************************
*
* main.cpp: Code to solve Barlas Exersice 3-12.
*
* Version 0.5 by Hartmut Weber: Just a template. 3-11 not solved.
2023-12-09 13:00:16 +00:00
* 1.0 by Robin Dietzel: Add QSemaphores to apply rules from 3-11 task
2023-12-09 12:53:56 +00:00
*
* Statemet of Version 1.0 Authorship:
2023-12-09 13:00:16 +00:00
* All added code to the template originates from my own.
2023-12-09 12:53:56 +00:00
*
**************************************************************************/
#include <QCoreApplication>
#include <QTimer>
#include <QThread>
#include <stdio.h>
#include <QSemaphore>
#include <QRandomGenerator>
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();
}