От: | Doom100500 | ||
Дата: | 13.06.21 11:25 | ||
Оценка: |
//worker.h
#ifdef WORKER_EXPORTS
#define WORKER_API __declspec(dllexport)
#else
#define WORKER_API __declspec(dllimport)
#endif
#include <string>
#include <memory>
#include <mutex>
struct WORKER_API WorkerBase {
virtual ~WorkerBase() {};
virtual void AddVal(const std::string& val) = 0;
};
class WorkerFactory {
public:
WORKER_API static WorkerBase* instance();
private:
static std::unique_ptr<WorkerBase> worker_ptr;
static std::once_flag once;
};
//worker.cpp
#include "pch.h"
#include "framework.h"
#include "Worker.h"
#include <string>
#include <deque>
#include <mutex>
#include <thread>
#include <iostream>
#include <chrono>
class Worker : public WorkerBase {
friend class WorkerFactory;
private:
public:
Worker() {
worker_thread = std::thread([this] {
std::cout << "started working thread" << std::endl;
while (is_running) {
std::unique_lock<std::mutex> lk(queue_lock);
queue_cv.wait(lk, [this] {return !queue.empty();});
if (!is_running) {
std::cout << "break" << std::endl;
}
std::cout << "got val: " << queue.front() << std::endl;
queue.pop_front();
}
std::cout << "exit working thread" << std::endl;
});
}
~Worker() {
queue_lock.lock();
is_running = false;
queue.push_back("last value");
queue_lock.unlock();
queue_cv.notify_one();
if (worker_thread.joinable())
worker_thread.join();
std::cout << "dtor completed" << std::endl;
}
void AddVal(const std::string& val) override {
queue_lock.lock();
queue.push_back(val);
queue_lock.unlock();
queue_cv.notify_one();
}
private:
std::deque<std::string> queue;
std::mutex queue_lock;
std::thread worker_thread;
std::condition_variable queue_cv;
std::atomic<bool> is_running = true;
};
std::unique_ptr<WorkerBase> WorkerFactory::worker_ptr;
std::once_flag WorkerFactory::once;
WorkerBase* WorkerFactory::instance() {
std::call_once(once, [] {worker_ptr = std::unique_ptr<WorkerBase>(new Worker);});
return worker_ptr.get();
}
#include <chrono>
#include <thread>
#include "../Worker/Worker.h"
int main() {
auto w = WorkerFactory::instance();
std::this_thread::sleep_for(std::chrono::seconds(1));
w->AddVal("1");
std::this_thread::sleep_for(std::chrono::seconds(1));
w->AddVal("2");
std::this_thread::sleep_for(std::chrono::seconds(1));
w->AddVal("3");
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0;
}
Я всю голову сломал почему я не вижу в output "exit working thread" и "got val: last value", но join отработал без проблем ?started working thread
got val: 1
got val: 2
got val: 3
dtor completed