Compare commits

...

6 Commits

Author SHA1 Message Date
f5a5bade28 reanme file 2023-12-05 21:33:25 +01:00
9abb7fcf26 Cleanup code 2023-12-05 21:32:22 +01:00
9ff5c03e6e Add custom implementation 2023-12-05 20:18:23 +01:00
35c98e180d fix issue 2023-12-05 10:57:17 +01:00
4144ab422e Revert "Remove unnecessary copy"
This reverts commit e732d062b6.
2023-12-05 10:54:45 +01:00
e732d062b6 Remove unnecessary copy 2023-12-05 10:53:51 +01:00
4 changed files with 124 additions and 107 deletions

View File

@ -19,28 +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);
std::vector<T> buf(data);
auto pivot = buf.begin();
std::advance(pivot, std::distance(buf.begin(), buf.end()) / 2);
auto lefti = buf.begin();
auto righti = buf.end();
auto lefti = data.begin();
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);
}
std::move(buf.begin(), buf.end(), data.begin());
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())};
}
@ -54,13 +50,9 @@ private:
}
}
// Determine mid of data
auto mid = data.begin();
std::advance(mid, std::distance(data.begin(), data.end()) / 2);
// Generate left and right view on data (no copies are made here)
std::span<T> left(data.begin(), mid);
std::span<T> right(mid, data.end());
auto res = parition(data);
auto &left = res.first;
auto &right = res.second;
if (depth < mdepth) {
std::thread left_thread([&]() { qsort(left, depth + 1, mdepth); });

View File

@ -1,10 +1,9 @@
find_package(Qt6 COMPONENTS Core REQUIRED)
add_executable(task3-chpt3ex12)
add_executable(task3-chpt3ex12-rd)
target_sources(task3-chpt3ex12 PRIVATE
main.cpp)
target_sources(task3-chpt3ex12-rd PRIVATE
main-rd.cpp)
target_link_libraries(task3-chpt3ex12 PRIVATE
target_link_libraries(task3-chpt3ex12-rd PRIVATE
Qt6::Core)

109
task3/main-rd.cpp Normal file
View File

@ -0,0 +1,109 @@
#include <iostream>
#include <QSemaphore>
#include <QThread>
#include <QCoreApplication>
/*
* Barlas Chpt 3 Ex 12:
Create three threads, each printing out the letters A, B, and C.
The printing must adhere to these rules:
The total number of Bs and Cs that have been output at any
point in the output string cannot exceed the total number
of As that have been output at that point.
After a C has been output, another C cannot be output until
one or more Bs have been output.
Use semaphores to solve the problem.
*/
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, typename ...Argts>
class Worker : public QThread {
private:
std::unique_ptr<IPrintable> printer_;
public:
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[]) {
//QCoreApplication app(argc, argv);
QSemaphore lockC(1);
QSemaphore lockBC(0);
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);
t1.start();
t2.start();
t3.start();
t1.wait();
t2.wait();
t3.wait();
//return app.exec();
return 0;
}

View File

@ -1,83 +0,0 @@
#include <iostream>
#include <QSemaphore>
#include <QThread>
#include <QCoreApplication>
/*
* Barlas Chpt 3 Ex 12:
Create three threads, each printing out the letters A, B, and C.
The printing must adhere to these rules:
The total number of Bs and Cs that have been output at any
point in the output string cannot exceed the total number
of As that have been output at that point.
After a C has been output, another C cannot be output until
one or more Bs have been output.
Use semaphores to solve the problem.
*/
class Printer {
private:
QSemaphore &lockBC_;
QSemaphore &lockC_;
QString name_;
public:
explicit Printer(QSemaphore &lockBC, QSemaphore &lockC, QString name) : lockBC_(lockBC), lockC_(lockC),
name_(name) {};
void printA() {
this->lockBC_.release(1);
std::cout << name_.toStdString() << " A\n";
}
void printB() {
if (this->lockBC_.tryAcquire(1, 10000)) {
if (this->lockC_.available() == 0) {
this->lockC_.release(1);
}
std::cout << name_.toStdString() << " B\n";
}
}
void printC() {
if (this->lockBC_.tryAcquire(1, 10000)) {
if (this->lockC_.tryAcquire(1, 10000)) {
std::cout << name_.toStdString() << " C\n";
} else {
this->lockBC_.release(1);
}
}
}
};
class Worker : public QThread {
private:
Printer printer_;
public:
Worker(QSemaphore &lockBC, QSemaphore &lockC, QString tname) : printer_(lockBC, lockC, tname) {};
protected:
void run() {
printer_.printA();
printer_.printB();
printer_.printC();
}
};
int main(int argc, char *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();
}
return app.exec();
}