1
0
This commit is contained in:
Sytnyk Yehor
2025-05-30 22:55:57 +03:00
parent 28ccfa72ac
commit e79109c81a
31 changed files with 1173 additions and 0 deletions

View File

@ -0,0 +1 @@
Hello from ./task-1/files/file1.txt

View File

@ -0,0 +1 @@
Hello from ./task-1/files/file2.txt

View File

@ -0,0 +1 @@
Hello from ./task-1/files/file3.txt

View File

@ -0,0 +1,36 @@
#include "queue.hpp"
#include "workers.hpp"
#include <format>
#include <fstream>
#include <ranges>
#include <string>
#include <thread>
#include <vector>
int main() {
std::string prefix = "./task-1/files";
th_safe::queue<std::string> queue;
std::vector<std::string> file_list = {
prefix + "/file1.txt", prefix + "/file2.txt", prefix + "/file3.txt"};
for (auto &&name : file_list) {
std::ofstream(name) << std::format("Hello from {}\n", name);
}
std::vector<std::jthread> producers;
for (std::int32_t i : std::views::iota(0, 2)) {
producers.emplace_back(workers::producer, std::ref(queue),
std::ref(file_list), i);
}
std::vector<std::jthread> consumers;
for (std::int32_t i : std::views::iota(0, 4)) {
consumers.emplace_back(workers::consumer, std::ref(queue), i);
}
producers.clear();
queue.done();
}

View File

@ -0,0 +1,45 @@
#pragma once
#include <condition_variable>
#include <mutex>
#include <optional>
#include <queue>
namespace th_safe {
template <typename T> class queue {
public:
void push(const T &value) {
{
std::lock_guard lock(mutex_);
queue_.push(value);
}
cond_var_.notify_one();
}
std::optional<T> pop() {
std::unique_lock lock(mutex_);
cond_var_.wait(lock, [this] { return !queue_.empty() || done_; });
if (queue_.empty())
return std::nullopt;
T value = queue_.front();
queue_.pop();
return value;
}
void done() {
{
std::lock_guard lock(mutex_);
done_ = true;
}
cond_var_.notify_all();
}
private:
std::queue<T> queue_;
std::mutex mutex_;
std::condition_variable cond_var_;
bool done_ = false;
};
} // namespace th_safe

View File

@ -0,0 +1,40 @@
#pragma once
#include "queue.hpp"
#include <chrono>
#include <fstream>
#include <print>
#include <string>
#include <thread>
#include <vector>
namespace workers {
void producer(th_safe::queue<std::string> &q,
const std::vector<std::string> &files, int id) {
for (const auto &file : files) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
q.push(file);
std::print("Produced ({}): {}\n", id, file);
}
}
void consumer(th_safe::queue<std::string> &q, int id) {
while (true) {
auto item = q.pop();
if (!item.has_value())
break;
std::ifstream file(item.value());
if (!file) {
std::print("Failed to open: {}\n", item.value());
continue;
}
std::print("Consumed ({}): {}\n", id, item.value());
for (std::string line; std::getline(file, line);) {
std::print("\t{}\n", line);
}
}
}
} // namespace workers