Add custom implementation

This commit is contained in:
Robin Dietzel 2023-12-05 20:18:23 +01:00
parent 35c98e180d
commit 9ff5c03e6e
2 changed files with 64 additions and 40 deletions

View File

@ -19,25 +19,24 @@ public:
private:
auto parition(std::span<T> &data) -> std::pair<std::span<T>, std::span<T>> {
auto pivot = data.begin();
std::advance(pivot, std::distance(data.begin(), data.end()) / 2);
auto lefti = data.begin();
auto righti = data.end();
auto righti = data.end() - 1;
while (1) {
for (; cmp(*lefti, *pivot); lefti++);
for (; !cmp(*righti, *pivot); righti--);
for (; cmp((*lefti), (*pivot)); lefti++);
for (; !cmp((*righti), (*pivot)); righti--);
if (lefti >= righti) {
break;
}
std::swap(lefti, righti);
std::swap(*lefti, *righti);
}
return {std::span<T>(data.begin(), lefti), std::span<T>(lefti, data.end())};
return {std::span<T>(data.begin(), pivot - 1), std::span<T>(pivot + 1, data.end())};
}
@ -52,8 +51,8 @@ private:
}
auto res = parition(data);
auto left = res.first;
auto right = res.second;
auto &left = res.first;
auto &right = res.second;
if (depth < mdepth) {
std::thread left_thread([&]() { qsort(left, depth + 1, mdepth); });

View File

@ -15,35 +15,52 @@
Use semaphores to solve the problem.
*/
class Printer {
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_;
QString name_;
public:
explicit Printer(QSemaphore &lockBC, QSemaphore &lockC, QString name) : lockBC_(lockBC), lockC_(lockC),
name_(name) {};
explicit PrintB(QSemaphore &lockBc, QSemaphore &lockC) : lockBC_(lockBc), lockC_(lockC) {}
void printA() {
this->lockBC_.release(1);
std::cout << name_.toStdString() << " A\n";
}
void printB() {
if (this->lockBC_.tryAcquire(1, 10000)) {
auto print() const -> void override {
if (this->lockBC_.tryAcquire(1)) {
if (this->lockC_.available() == 0) {
this->lockC_.release(1);
}
std::cout << name_.toStdString() << " B\n";
std::cout << "B";
}
}
};
void printC() {
if (this->lockBC_.tryAcquire(1, 10000)) {
if (this->lockC_.tryAcquire(1, 10000)) {
std::cout << name_.toStdString() << " C\n";
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);
}
@ -51,33 +68,41 @@ public:
}
};
template<typename T, typename ...Argts>
class Worker : public QThread {
private:
Printer printer_;
std::unique_ptr<IPrintable> printer_;
public:
Worker(QSemaphore &lockBC, QSemaphore &lockC, QString tname) : printer_(lockBC, lockC, tname) {};
Worker(QString tname, Argts &... args) : printer_(std::make_unique<T>(args...)) {};
protected:
void run() {
printer_.printA();
printer_.printB();
printer_.printC();
while (true) {
printer_->print();
std::cout.flush();
sleep(1);
}
}
};
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
//QCoreApplication app(argc, argv);
QSemaphore lockC(1);
QSemaphore lockBC(0);
int N = 3;
Worker *workers[N];
for (int i = 0; i < N; i++) {
workers[i] = new Worker(lockBC, lockC, QString("Thread %1").arg(i));
workers[i]->start();
}
Worker<PrintA, QSemaphore> t1("Thread 1", lockBC);
Worker<PrintB, QSemaphore, QSemaphore> t2("Thread 1", lockBC, lockC);
Worker<PrintC, QSemaphore, QSemaphore> t3("Thread 1", lockBC, lockC);
return app.exec();
t1.start();
t2.start();
t3.start();
t1.wait();
t2.wait();
t3.wait();
//return app.exec();
return 0;
}