Add custom implementation
This commit is contained in:
parent
35c98e180d
commit
9ff5c03e6e
@ -19,25 +19,24 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
auto parition(std::span<T> &data) -> std::pair<std::span<T>, std::span<T>> {
|
auto parition(std::span<T> &data) -> std::pair<std::span<T>, std::span<T>> {
|
||||||
|
|
||||||
auto pivot = data.begin();
|
auto pivot = data.begin();
|
||||||
std::advance(pivot, std::distance(data.begin(), data.end()) / 2);
|
std::advance(pivot, std::distance(data.begin(), data.end()) / 2);
|
||||||
|
|
||||||
auto lefti = data.begin();
|
auto lefti = data.begin();
|
||||||
auto righti = data.end();
|
auto righti = data.end() - 1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
for (; cmp(*lefti, *pivot); lefti++);
|
for (; cmp((*lefti), (*pivot)); lefti++);
|
||||||
for (; !cmp(*righti, *pivot); righti--);
|
for (; !cmp((*righti), (*pivot)); righti--);
|
||||||
|
|
||||||
if (lefti >= righti) {
|
if (lefti >= righti) {
|
||||||
break;
|
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 res = parition(data);
|
||||||
auto left = res.first;
|
auto &left = res.first;
|
||||||
auto right = res.second;
|
auto &right = res.second;
|
||||||
|
|
||||||
if (depth < mdepth) {
|
if (depth < mdepth) {
|
||||||
std::thread left_thread([&]() { qsort(left, depth + 1, mdepth); });
|
std::thread left_thread([&]() { qsort(left, depth + 1, mdepth); });
|
||||||
|
@ -15,35 +15,52 @@
|
|||||||
Use semaphores to solve the problem.
|
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:
|
private:
|
||||||
QSemaphore &lockBC_;
|
QSemaphore &lockBC_;
|
||||||
QSemaphore &lockC_;
|
QSemaphore &lockC_;
|
||||||
|
|
||||||
QString name_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Printer(QSemaphore &lockBC, QSemaphore &lockC, QString name) : lockBC_(lockBC), lockC_(lockC),
|
explicit PrintB(QSemaphore &lockBc, QSemaphore &lockC) : lockBC_(lockBc), lockC_(lockC) {}
|
||||||
name_(name) {};
|
|
||||||
|
|
||||||
void printA() {
|
auto print() const -> void override {
|
||||||
this->lockBC_.release(1);
|
if (this->lockBC_.tryAcquire(1)) {
|
||||||
std::cout << name_.toStdString() << " A\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void printB() {
|
|
||||||
if (this->lockBC_.tryAcquire(1, 10000)) {
|
|
||||||
if (this->lockC_.available() == 0) {
|
if (this->lockC_.available() == 0) {
|
||||||
this->lockC_.release(1);
|
this->lockC_.release(1);
|
||||||
}
|
}
|
||||||
std::cout << name_.toStdString() << " B\n";
|
std::cout << "B";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void printC() {
|
class PrintC : public IPrintable {
|
||||||
if (this->lockBC_.tryAcquire(1, 10000)) {
|
private:
|
||||||
if (this->lockC_.tryAcquire(1, 10000)) {
|
QSemaphore &lockBC_;
|
||||||
std::cout << name_.toStdString() << " C\n";
|
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 {
|
} else {
|
||||||
this->lockBC_.release(1);
|
this->lockBC_.release(1);
|
||||||
}
|
}
|
||||||
@ -51,33 +68,41 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename T, typename ...Argts>
|
||||||
class Worker : public QThread {
|
class Worker : public QThread {
|
||||||
private:
|
private:
|
||||||
Printer printer_;
|
std::unique_ptr<IPrintable> printer_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Worker(QSemaphore &lockBC, QSemaphore &lockC, QString tname) : printer_(lockBC, lockC, tname) {};
|
Worker(QString tname, Argts &... args) : printer_(std::make_unique<T>(args...)) {};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void run() {
|
void run() {
|
||||||
printer_.printA();
|
while (true) {
|
||||||
printer_.printB();
|
printer_->print();
|
||||||
printer_.printC();
|
std::cout.flush();
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
QCoreApplication app(argc, argv);
|
//QCoreApplication app(argc, argv);
|
||||||
QSemaphore lockC(1);
|
QSemaphore lockC(1);
|
||||||
QSemaphore lockBC(0);
|
QSemaphore lockBC(0);
|
||||||
|
|
||||||
int N = 3;
|
Worker<PrintA, QSemaphore> t1("Thread 1", lockBC);
|
||||||
Worker *workers[N];
|
Worker<PrintB, QSemaphore, QSemaphore> t2("Thread 1", lockBC, lockC);
|
||||||
for (int i = 0; i < N; i++) {
|
Worker<PrintC, QSemaphore, QSemaphore> t3("Thread 1", lockBC, lockC);
|
||||||
workers[i] = new Worker(lockBC, lockC, QString("Thread %1").arg(i));
|
|
||||||
workers[i]->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
return app.exec();
|
t1.start();
|
||||||
|
t2.start();
|
||||||
|
t3.start();
|
||||||
|
|
||||||
|
t1.wait();
|
||||||
|
t2.wait();
|
||||||
|
t3.wait();
|
||||||
|
//return app.exec();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user