文章目录
- 一.C++11 中的<future>
- 二.future 对象
- 三.async 全局函数
- 四.promise::get_future
- 五.packaged_task::get_future
- 六.使用 packaged_task 和 future 实现可获取结果的线程池
一.C++11 中的
二.future 对象
三.async 全局函数
#include <iostream>
#include <future>
#include <chrono>
#include <thread>
int Add(int x, int y)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
return x + y;
}
int main()
{
std::future<int> fu = std::async(std::launch::async, Add, 1, 2);
int ret = fu.get();
std::cout << "ret = " << ret << std::endl;
return 0;
}
四.promise::get_future
#include <iostream>
#include <future>
#include <chrono>
#include <thread>
int Add(int x, int y)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
return x + y;
}
int main()
{
std::future<int> fu = std::async(std::launch::async, Add, 1, 2);
int ret = fu.get();
std::cout << "ret = " << ret << std::endl;
return 0;
}
五.packaged_task::get_future
#include <iostream>
#include <future>
#include <chrono>
#include <thread>
#include <memory>
using namespace std;
int Add(int x, int y)
{
std::this_thread::sleep_for(std::chrono::seconds(5));
return x + y;
}
int main()
{
auto ptaskPtr = std::make_shared<packaged_task<int(int, int)>>(Add);
future<int> fu = ptaskPtr->get_future();
thread t1([ptaskPtr]{
(*ptaskPtr)(1, 2);
});
int ret = fu.get();
std::cout << ret << std::endl;
t1.join();
return 0;
}
六.使用 packaged_task 和 future 实现可获取结果的线程池
ThreadPool.hpp
#pragma once
#include <thread>
#include <mutex>
#include <condition_variable>
#include <memory>
#include <atomic>
#include <vector>
#include <queue>
#include <functional>
#include <iostream>
#include <future>
static const int defaultThreadNum = 5;
class ThreadPool
{
public:
using task_t = std::function<void()>;
private:
std::vector<std::thread> _workers;
std::queue<task_t> _tasks;
std::mutex _mtx;
std::condition_variable _cond;
std::atomic<bool> _isRunning;
int _threadNum;
public:
ThreadPool(int threadNum = defaultThreadNum)
: _workers(),
_tasks(),
_mtx(),
_cond(),
_isRunning(false),
_threadNum(threadNum)
{
}
~ThreadPool()
{
for (auto& t : _workers)
{
t.join();
}
}
void start()
{
for (int i = 0; i < _threadNum; i++)
{
_workers.emplace_back(&ThreadPool::work, this);
}
_isRunning = true;
}
template <typename Fn, typename ...Args>
auto push(Fn&& func, Args&& ... args) -> std::future<decltype(func(args...))>
{
using return_t = decltype(func(args...));
if (!_isRunning)
{
std::cout << "Please start threadPool first" << std::endl;
return std::future<return_t>();
}
//1.把这个任务的参数绑定,变成一个返回值位return_t,参数为void的可调用对象
auto tmpFunc = std::bind(std::forward<Fn>(func), std::forward<Args>(args)...);
//2.把这个bind后的可调用对象用packaged_task封装,用智能指针管理
auto ptaskPtr = std::make_shared<std::packaged_task<return_t()>>(tmpFunc);
//3.把智能指针封装到lambda表达式中解引用执行,并把lambda表达式丢进任务队列
task_t task = [ptaskPtr](){(*ptaskPtr)();};
std::unique_lock<std::mutex> lck(_mtx);
_tasks.push(task);
_cond.notify_one();
return ptaskPtr->get_future();
}
private:
void work()
{
while (true)
{
task_t task;
{
std::unique_lock<std::mutex> lck(_mtx);
// 判断条件是否成立
while (_tasks.empty())
{
_cond.wait(lck);
}
task = _tasks.front();
_tasks.pop();
}
task();
}
}
};