OS lb-8
This commit is contained in:
1
semester-4/ОС/lb-8/src/task-1/files/file1.txt
Normal file
1
semester-4/ОС/lb-8/src/task-1/files/file1.txt
Normal file
@ -0,0 +1 @@
|
||||
Hello from ./task-1/files/file1.txt
|
1
semester-4/ОС/lb-8/src/task-1/files/file2.txt
Normal file
1
semester-4/ОС/lb-8/src/task-1/files/file2.txt
Normal file
@ -0,0 +1 @@
|
||||
Hello from ./task-1/files/file2.txt
|
1
semester-4/ОС/lb-8/src/task-1/files/file3.txt
Normal file
1
semester-4/ОС/lb-8/src/task-1/files/file3.txt
Normal file
@ -0,0 +1 @@
|
||||
Hello from ./task-1/files/file3.txt
|
36
semester-4/ОС/lb-8/src/task-1/main.cpp
Normal file
36
semester-4/ОС/lb-8/src/task-1/main.cpp
Normal 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();
|
||||
}
|
45
semester-4/ОС/lb-8/src/task-1/queue.hpp
Normal file
45
semester-4/ОС/lb-8/src/task-1/queue.hpp
Normal 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
|
40
semester-4/ОС/lb-8/src/task-1/workers.hpp
Normal file
40
semester-4/ОС/lb-8/src/task-1/workers.hpp
Normal 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
|
Reference in New Issue
Block a user