21xrx.com
2024-09-19 10:13:12 Thursday
登录
文章检索 我的文章 写文章
C++ 打包任务 (packaged_task)
2023-07-04 21:53:19 深夜i     --     --
C++ 打包任务 PackagedTask 异步编程 并发编程

C++是一门强大的编程语言,支持多种编程模型,其中异步编程模型也是C++程序员必备的技能。C++11引入了std::packaged_task,提供了一种方便的方式,使得函数可以异步执行,并能够得到返回值。

std::packaged_task是一种可以包装函数或者可调用对象的模板类,通过将函数或可调用对象和std::promise对象结合起来,形成一个“打包任务”,这个任务可以被异步执行。std::packaged_task在定义时需要声明返回值类型和参数类型,当调用时,需要将参数传递给std::packaged_task对象,并调用std::packaged_task对象,这样就可以异步执行任务了。

使用std::packaged_task的流程大致如下:

1. 创建一个std::packaged_task对象,指定任务的类型,包括返回值类型和参数类型。

2. 将std::packaged_task对象的get_future()方法返回的std::future对象传递给异步执行的线程。

3. 异步线程执行任务时,将传递给线程的函数指针或可调用对象作为参数调用std::packaged_task对象。

4. 在异步线程执行函数或可调用对象的过程中,可以通过std::promise对象设置返回值。

5. 主线程通过std::future对象的get()方法获取异步线程执行后的返回值。

下面是一个简单的示例代码:


#include <iostream>

#include <thread>

#include <future>

void my_task(std::promise<int> data_promise) {

  std::this_thread::sleep_for(std::chrono::seconds(1));

  int result = 42;

  data_promise.set_value(result);

}

int main() {

  std::packaged_task<int()> my_ptask(my_task);

  std::future<int> my_future = my_ptask.get_future();

  std::thread my_thread(std::move(my_ptask), std::move(my_future));

  std::cout << "Waiting for result..." << std::endl;

  int result = my_future.get();

  std::cout << "The result is: " << result << std::endl;

  my_thread.join();

  return 0;

}

以上代码定义了一个名为my_task()的函数,它接受一个std::promise 类型的参数,执行后将结果设置到std::promise 对象中。然后,我们创建了一个std::packaged_task对象my_ptask,并将my_task函数作为参数传递给它。接下来,我们通过my_ptask.get_future()方法获取了一个std::future 对象,用于在主线程中查看异步任务执行后的返回值。

然后它创建了一个线程my_thread,并将std::packaged_task对象my_ptask和std::future对象my_future移动到线程中,并启动线程异步执行。这时候,主线程等待异步任务执行完毕,并通过std::future对象的get()方法获取my_task执行后的结果,并输出到控制台输出。

需要注意的是:std::packaged_task对象只能被调用一次,因为std::future对象只能获取一个返回值。如果需要重复执行任务,需要重新创建std::packaged_task对象。此外,如果不进行std::move操作,直接传递std::packaged_task对象,编译器会报错,因为std::packaged_task对象不能被拷贝,只能被移动。

总结来说,std::packaged_task是C++11提供的一个非常好用的异步任务执行工具,它通过方便的方式将函数或者可调用对象打包成任务,并异步执行。同时,通过使用std::promise和std::future对象,我们也可以非常方便地获取异步任务执行后的返回值。C++程序员们可以根据自己的需求,灵活地使用std::packaged_task进行异步编程。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复