aca-tasks/task3/main-rd.cpp

98 lines
2.0 KiB
C++
Raw Normal View History

2023-12-02 13:34:06 +00:00
#include <iostream>
#include <QSemaphore>
#include <QThread>
#include <QCoreApplication>
2023-12-05 19:18:23 +00:00
struct IPrintable {
~IPrintable() = default;
2023-12-02 13:55:13 +00:00
2023-12-05 19:18:23 +00:00
virtual auto print() const -> void = 0;
};
2023-12-02 13:34:06 +00:00
2023-12-05 19:18:23 +00:00
class PrintA : public IPrintable {
private:
QSemaphore &lockBC_;
2023-12-02 13:34:06 +00:00
public:
2023-12-05 19:18:23 +00:00
explicit PrintA(QSemaphore &lockBc) : lockBC_(lockBc) {}
2023-12-02 13:34:06 +00:00
2023-12-05 19:18:23 +00:00
auto print() const -> void override {
2023-12-02 13:55:13 +00:00
this->lockBC_.release(1);
2023-12-05 19:18:23 +00:00
std::cout << "A";
2023-12-02 13:34:06 +00:00
}
2023-12-05 19:18:23 +00:00
};
class PrintB : public IPrintable {
private:
QSemaphore &lockBC_;
QSemaphore &lockC_;
public:
explicit PrintB(QSemaphore &lockBc, QSemaphore &lockC) : lockBC_(lockBc), lockC_(lockC) {}
2023-12-02 13:34:06 +00:00
2023-12-05 19:18:23 +00:00
auto print() const -> void override {
if (this->lockBC_.tryAcquire(1)) {
2023-12-02 13:55:13 +00:00
if (this->lockC_.available() == 0) {
this->lockC_.release(1);
2023-12-02 13:34:06 +00:00
}
2023-12-05 19:18:23 +00:00
std::cout << "B";
2023-12-02 13:34:06 +00:00
}
}
2023-12-05 19:18:23 +00:00
};
class PrintC : public IPrintable {
private:
QSemaphore &lockBC_;
QSemaphore &lockC_;
public:
explicit PrintC(QSemaphore &lockBc, QSemaphore &lockC) : lockBC_(lockBc), lockC_(lockC) {}
2023-12-02 13:34:06 +00:00
2023-12-05 19:18:23 +00:00
auto print() const -> void override {
if (this->lockBC_.tryAcquire(1)) {
if (this->lockC_.tryAcquire(1)) {
std::cout << "C";
2023-12-02 13:34:06 +00:00
} else {
2023-12-02 13:55:13 +00:00
this->lockBC_.release(1);
2023-12-02 13:34:06 +00:00
}
}
}
};
2023-12-05 19:18:23 +00:00
2023-12-07 20:39:28 +00:00
template<typename T>
2023-12-02 13:34:06 +00:00
class Worker : public QThread {
private:
2023-12-05 19:18:23 +00:00
std::unique_ptr<IPrintable> printer_;
2023-12-02 13:34:06 +00:00
public:
2023-12-07 20:39:28 +00:00
template<typename ...Argts>
2023-12-05 19:18:23 +00:00
Worker(QString tname, Argts &... args) : printer_(std::make_unique<T>(args...)) {};
2023-12-02 13:34:06 +00:00
protected:
void run() {
2023-12-05 19:18:23 +00:00
while (true) {
printer_->print();
std::cout.flush();
sleep(1);
}
2023-12-02 13:34:06 +00:00
}
};
int main(int argc, char *argv[]) {
2023-12-05 20:32:22 +00:00
2023-12-02 13:34:06 +00:00
QSemaphore lockC(1);
QSemaphore lockBC(0);
2023-12-07 20:39:28 +00:00
Worker<PrintA> t1("Thread 1", lockBC);
Worker<PrintB> t2("Thread 1", lockBC, lockC);
Worker<PrintC> t3("Thread 1", lockBC, lockC);
2023-12-05 19:18:23 +00:00
t1.start();
t2.start();
t3.start();
2023-12-02 13:34:06 +00:00
2023-12-05 19:18:23 +00:00
t1.wait();
t2.wait();
t3.wait();
2023-12-09 12:22:46 +00:00
2023-12-05 19:18:23 +00:00
return 0;
2023-12-02 13:34:06 +00:00
}