Fixed a timing bug
That would cause the thread to not be reported as busy while putting the task on-to the thread.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <stdexcept>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
#include <MultiThreading/Task.h>
|
||||
|
||||
namespace MultiThreading {
|
||||
@@ -13,12 +14,13 @@ namespace MultiThreading {
|
||||
|
||||
class MultiThreading::Thread {
|
||||
private:
|
||||
std::thread worker;
|
||||
std::function<void(Thread* thread, std::shared_ptr<TaskBase> task)> on_task_complete_callback = nullptr;
|
||||
std::shared_ptr<TaskBase> current_task = nullptr;
|
||||
std::atomic<bool> busy = false;
|
||||
std::mutex mtx;
|
||||
std::condition_variable cv;
|
||||
std::atomic<bool> stop = false;
|
||||
std::condition_variable cv;
|
||||
std::thread worker;
|
||||
std::mutex mtx;
|
||||
bool busy = false;
|
||||
private:
|
||||
void Runner();
|
||||
public:
|
||||
@@ -26,6 +28,7 @@ public:
|
||||
[[nodiscard]] bool SetTask(std::shared_ptr<TaskBase> task);
|
||||
[[nodiscard]] bool Busy() const { return busy; }
|
||||
void Join() { if (worker.joinable()) worker.join(); };
|
||||
void SetTaskCompletionCallback(std::function<void(Thread*, std::shared_ptr<TaskBase>)> callback) { on_task_complete_callback = std::move(callback); };
|
||||
public:
|
||||
Thread() { worker = std::thread([this] { this->Runner(); }); }
|
||||
explicit Thread(std::shared_ptr<TaskBase> task);
|
||||
|
12
main.cpp
12
main.cpp
@@ -6,11 +6,15 @@
|
||||
|
||||
using namespace MultiThreading;
|
||||
int32_t some_test_func(int32_t hello) {
|
||||
for (unsigned int i = 0; i < 100; i++)
|
||||
for (unsigned int i = 0; i < 50; i++)
|
||||
std::cout << i << std::endl;
|
||||
return hello;
|
||||
}
|
||||
|
||||
void cb(Thread* thread, std::shared_ptr<TaskBase> task) {
|
||||
std::cout << thread->Busy() << std::endl;
|
||||
std::cout << task->Complete() << std::endl;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Each task you create can be run by a thread only once. It's marked as complete after.
|
||||
@@ -21,8 +25,14 @@ int main() {
|
||||
// You can start threads in place like this, but you have to wait for the amount of time
|
||||
// it takes for the thread to start up which in many cases is longer than the job. Use thread pool.
|
||||
Thread some_thread;
|
||||
//some_thread.SetTaskCompletionCallback(cb);
|
||||
some_thread.SetTask(some_task);
|
||||
|
||||
//while (!some_task->Complete()) {}
|
||||
|
||||
//std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
std::cout << some_thread.Busy() << std::endl;
|
||||
|
||||
// Some work running concurrently with the worker thread.
|
||||
//for (unsigned int i = 0; i < 10; i++) {}
|
||||
|
||||
|
@@ -1,6 +1,4 @@
|
||||
#include <MultiThreading/Thread.h>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
using namespace MultiThreading;
|
||||
@@ -9,17 +7,24 @@ Thread::~Thread() {
|
||||
if (current_task)
|
||||
while (!current_task->Complete()) {}
|
||||
stop = true;
|
||||
|
||||
cv.notify_one();
|
||||
Join();
|
||||
// Thread exits gracefully.
|
||||
}
|
||||
|
||||
bool Thread::SetTask(std::shared_ptr<TaskBase> task) {
|
||||
if (busy)
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
|
||||
if (Busy())
|
||||
return false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
current_task = std::move(task);
|
||||
}
|
||||
|
||||
if (current_task)
|
||||
return false;
|
||||
|
||||
busy = true;
|
||||
current_task = std::move(task);
|
||||
|
||||
cv.notify_all();
|
||||
return true;
|
||||
}
|
||||
@@ -30,17 +35,19 @@ bool Thread::SetTask(const std::function<void()>& task) {
|
||||
|
||||
void Thread::Runner() {
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
|
||||
while (!stop) {
|
||||
cv.wait(lock, [this] { return stop || current_task != nullptr; });
|
||||
|
||||
if (stop)
|
||||
break;
|
||||
|
||||
busy = true;
|
||||
|
||||
lock.unlock();
|
||||
if (current_task)
|
||||
current_task->Run();
|
||||
|
||||
current_task->Run();
|
||||
|
||||
if (on_task_complete_callback)
|
||||
on_task_complete_callback(this, current_task);
|
||||
|
||||
lock.lock();
|
||||
|
||||
|
Reference in New Issue
Block a user