older thread pool impl with perfect forwarding, to recall later
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
class ThreadPool {
|
||||
private:
|
||||
vector<thread> workers;
|
||||
queue<function<void()>> tasks;
|
||||
mutex mtx;
|
||||
condition_variable cv;
|
||||
bool stop = false;
|
||||
|
||||
public:
|
||||
ThreadPool(int num_threads) {
|
||||
while (num_threads-- > 0) {
|
||||
workers.emplace_back([this] {
|
||||
while (true) {
|
||||
function<void()> task;
|
||||
{
|
||||
unique_lock<mutex> lock(mtx);
|
||||
cv.wait(lock,
|
||||
[this] { return stop || !tasks.empty(); });
|
||||
|
||||
if (stop && tasks.empty()) return;
|
||||
|
||||
task = std::move(tasks.front());
|
||||
tasks.pop();
|
||||
}
|
||||
task();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
template <typename F, typename... Args>
|
||||
future<typename result_of<F(Args...)>::type> enqueue(F&& f,
|
||||
Args&&... args) {
|
||||
if (stop) throw std::runtime_error("enqueue on stopped ThreadPool");
|
||||
|
||||
using return_type = typename std::result_of<F(Args...)>::type;
|
||||
// this is not calling the return type its a func with no args and
|
||||
// returning return type value as in int(int) this is int()
|
||||
auto task = make_shared<packaged_task<return_type()>>(
|
||||
bind(forward<F>(f), forward<Args>(args)...));
|
||||
future<return_type> fut = task->get_future();
|
||||
// since its a share pointer so the task lives as long as future lives
|
||||
// you could not make it shared but then pool might die with future
|
||||
// being invalid now the desctructor isn't called now unless the future
|
||||
// also goes out of scope
|
||||
|
||||
{
|
||||
unique_lock<mutex> lock(mtx);
|
||||
tasks.emplace([task] { (*task)(); });
|
||||
}
|
||||
|
||||
cv.notify_one();
|
||||
return fut;
|
||||
}
|
||||
|
||||
~ThreadPool() {
|
||||
{
|
||||
unique_lock<mutex> lock(mtx);
|
||||
stop = true;
|
||||
}
|
||||
|
||||
cv.notify_all();
|
||||
for (auto& worker : workers) worker.join();
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
ThreadPool pool(4);
|
||||
|
||||
auto taskFunction = [](int a, int& b, std::string&& c) {
|
||||
std::cout << "Task executed with: " << a << ", " << b << ", " << c
|
||||
<< std::endl;
|
||||
b *= 2; // Modify the lvalue reference
|
||||
return a + b;
|
||||
};
|
||||
|
||||
int lval = 10;
|
||||
auto future = pool.enqueue(taskFunction, 5, ref(lval), "hello");
|
||||
|
||||
cout << "result: " << future.get() << endl;
|
||||
}
|
||||
Reference in New Issue
Block a user