Last active
September 7, 2015 03:28
-
-
Save Preetam/7844f32f65fd7e1d8819 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <future> | |
#include <functional> | |
#include <memory> | |
#include <chrono> | |
class abstract_task { | |
public: | |
virtual bool ready() = 0; | |
virtual void operator()() = 0; | |
virtual ~abstract_task() {}; | |
}; | |
template<class T> | |
class waiting_task : abstract_task | |
{ | |
public: | |
using future_ptr = std::unique_ptr<std::future<T>>; | |
using task_ptr = std::unique_ptr<std::packaged_task<void(future_ptr)>>; | |
future_ptr fut; | |
task_ptr _task; | |
waiting_task(future_ptr fut, task_ptr task) | |
: fut(std::move(fut)), _task(std::move(task)) | |
{ | |
} | |
bool | |
ready() { | |
auto status = fut->wait_for(std::chrono::seconds(0)); | |
if (status == std::future_status::ready) { | |
return true; | |
} | |
return false; | |
} | |
void | |
operator()() { | |
(*_task)(std::move(fut)); | |
} | |
}; | |
class packaged_task : public abstract_task | |
{ | |
private: | |
std::unique_ptr<std::packaged_task<void()>> _task; | |
public: | |
packaged_task(std::unique_ptr<std::packaged_task<void()>> task) | |
: _task(std::move(task)) | |
{ | |
} | |
bool | |
ready() { | |
return true; | |
} | |
void | |
operator()() { | |
(*_task)(); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// g++ -std=c++14 -o taskpool taskpool.cc -lpthread | |
// ./taskpool | |
#include <iostream> | |
#include <functional> | |
#include <future> | |
#include <thread> | |
#include <chrono> | |
#include <mutex> | |
#include <queue> | |
#include <memory> | |
#include <atomic> | |
#include "task.hpp" | |
class taskpool { | |
public: | |
template<typename T> using task_t = std::packaged_task<T>; | |
template<typename T> using task_uptr = std::unique_ptr<task_t<T>>; | |
std::atomic_bool quit; | |
std::queue<task_uptr<void()>> tasks; | |
std::mutex task_list_mutex; | |
std::unique_ptr<std::thread> runner; | |
void | |
add_task(task_uptr<void()> task) { | |
std::lock_guard<std::mutex> lock(task_list_mutex); | |
tasks.push(std::move(task)); | |
} | |
task_uptr<void()> | |
get_task() { | |
std::lock_guard<std::mutex> lock(task_list_mutex); | |
if (tasks.size() == 0) { | |
return nullptr; | |
} | |
auto task_ptr = std::move(tasks.front()); | |
tasks.pop(); | |
return task_ptr; | |
} | |
void | |
run() { | |
quit = false; | |
using namespace std::literals; | |
runner = std::move(std::make_unique<std::thread>([this](){ | |
while (true) { | |
if (quit) { | |
return; | |
} | |
auto taskptr = get_task(); | |
if (taskptr) { | |
(*taskptr)(); | |
} else { | |
std::this_thread::sleep_for(100us); | |
} | |
} | |
})); | |
} | |
void | |
join() { | |
runner->join(); | |
} | |
}; | |
void | |
printer() { | |
std::cout << "printer()" << std::endl; | |
} | |
void | |
slow_function() { | |
using namespace std::literals; | |
std::cout << "starting slow function" << std::endl; | |
std::this_thread::sleep_for(0.5s); | |
std::cout << "finished slow function" << std::endl; | |
} | |
int | |
main() { | |
auto pool = std::make_shared<taskpool>(); | |
pool->run(); | |
pool->add_task(std::make_unique<std::packaged_task<void()>>(printer)); | |
auto slow_task = std::make_unique<std::packaged_task<void()>>(slow_function); | |
auto slow_task_future_ptr = std::make_unique<std::future<void>>((*slow_task).get_future()); | |
pool->add_task(std::move(slow_task)); | |
auto printer_task = std::make_unique<std::packaged_task<void()>>(printer); | |
std::unique_ptr<abstract_task> abs_task = std::make_unique<packaged_task>(std::move(printer_task)); | |
if (abs_task->ready()) { | |
(*abs_task)(); | |
} | |
auto slow_function_callback = std::make_unique< | |
std::packaged_task< | |
void(std::unique_ptr<std::future<void>>) | |
> | |
>([pool](std::unique_ptr<std::future<void>> fut) { | |
std::cout << "slow_function_callback()" << std::endl; | |
pool->quit = true; | |
pool->join(); | |
}); | |
waiting_task<void> waits_for_slow_task(std::move(slow_task_future_ptr), std::move(slow_function_callback)); | |
while (!waits_for_slow_task.ready()) { | |
} | |
waits_for_slow_task(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment