打包任务 |高级 C++(多线程和多处理)
std::packaged_task 类包装任何 Callable 对象(函数、lambda 表达式、绑定表达式或另一个函数对象),以便可以异步调用它们。 packaged_task 不会自行启动,您必须调用它,因为它的返回值存储在可以由 std::future 对象调用/访问的共享状态中。
需要打包任务
打包任务的主要优点是它可以将可调用对象链接到未来,这在泛洪环境中非常重要。例如,如果我们有一个从数据库 (DB) 获取数据并返回的现有函数。现在需要在单独的线程中执行这个函数。这可以使用以下方法完成:
std::packaged_task<>
否则,我们将不得不使用:
std::promise<>
并且必须更改代码,但在 std::packaged_task<> 的帮助下它很简单,我们不需要这样做。
成员函数
packaged_task 中的一些成员函数是:
- Operator=-它移动打包的任务,它是一个公共成员函数。
- 交换——它只是交换到打包的任务,或者你可以说相互交换两个打包的任务。
- get_future -它返回一个与承诺结果相关的 std::future。
- 重置 -这个公共成员函数只是重置任务。
- (构造函数)-顾名思义,这个公共成员函数构造了打包的任务。
- (destructor) -类似地,(destructor) 破坏任务对象。
非成员函数
非成员函数之一是:
- swap(packaged_task) -它专门用于 std::swap 算法。
下面是实现上述功能的C++程序——
C++
// C++ program to implement
// the functions
#include
using namespace std;
// Factorial function
int factorial(int N)
{
int res = 1;
for (int i = N; i > 1; i--)
{
res *= i;
}
cout << "Result is = " <<
res << "/n";
return res;
}
// packaged task
std::deque > task_q;
std::mutex mu;
std::condition_variable cond;
void thread1()
{
// packaged task
std::packaged_task t;
{
std::unique_lock locker(mu);
cond.wait(locker, []()
{
return !task_q.empty();
});
t = std::move(task_q.front());
task_q.pop_front();
}
t();
}
// Driver Code
int main()
{
std::thread t1(thread1);
// Create a packaged_task<> that
// encapsulated the callback i.e. a function
std::packaged_task t(bind(factorial,6));
// Fetch the associated future<>
// from packaged_task<>
std::future fu = t.get_future();
{
std::lock_guard locker(mu);
task_q.push_back(std::move(t));
}
cond.notify_one();
// Fetch the result of packaged_task<>
cout<
输出: