aca-tasks/task3/main-rd.cpp
2023-12-09 13:22:46 +01:00

98 lines
2.0 KiB
C++

#include <iostream>
#include <QSemaphore>
#include <QThread>
#include <QCoreApplication>
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<typename T>
class Worker : public QThread {
private:
std::unique_ptr<IPrintable> printer_;
public:
template<typename ...Argts>
Worker(QString tname, Argts &... args) : printer_(std::make_unique<T>(args...)) {};
protected:
void run() {
while (true) {
printer_->print();
std::cout.flush();
sleep(1);
}
}
};
int main(int argc, char *argv[]) {
QSemaphore lockC(1);
QSemaphore lockBC(0);
Worker<PrintA> t1("Thread 1", lockBC);
Worker<PrintB> t2("Thread 1", lockBC, lockC);
Worker<PrintC> t3("Thread 1", lockBC, lockC);
t1.start();
t2.start();
t3.start();
t1.wait();
t2.wait();
t3.wait();
return 0;
}