首页 > 其他分享 >std::packaged_task<返回类型(参数类型)>

std::packaged_task<返回类型(参数类型)>

时间:2024-10-07 12:00:09浏览次数:11  
标签:std 异步 task packaged future 线程

std::packaged_task 概述

std::packaged_task 是 C++11 引入的标准库模板类,用于包装一个可调用对象(如函数、lambda 表达式、函数对象等),使其能够与 std::future 协同工作

简单来说,它将一个任务(可调用对象)包装起来,并允许你获取该任务的执行结果,这样你可以在一个线程中执行任务,并在另一个线程中获取其结果。

std::packaged_taskstd::futurestd::promise 一起,提供了异步任务执行和结果传递的功能。

基本功能

  • 包装可调用对象:通过 std::packaged_task 包装一个函数或可调用对象,类似于把任务“打包”起来。
  • 异步执行任务:将 packaged_task 对象交由线程执行,异步地处理任务。
  • 获取任务结果:通过关联的 std::future 对象,获取异步任务的结果。

用法和示例

1. 基本用法

下面是一个使用 std::packaged_task 包装函数并在不同线程中执行任务的简单示例:

#include <iostream>
#include <future>
#include <thread>
#include <chrono>

// 一个简单的函数,用于计算整数平方
int square(int x) {
    std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作
    return x * x;
}

int main() {
    // 创建一个 std::packaged_task,包装 square 函数
    std::packaged_task<int(int)> task(square);

    // 获取关联的 std::future 对象,用于获取任务结果
    std::future<int> result = task.get_future();

    // 将任务交给一个线程异步执行
    std::thread t(std::move(task), 5); // 传递参数5给square函数
    t.detach(); // 分离线程

    // 在主线程中继续做其他事情
    std::cout << "Doing some work in the main thread..." << std::endl;

    // 获取任务的返回值,等待任务执行完成
    std::cout << "The result of square(5) is: " << result.get() << std::endl;

    return 0;
}

2. 逐步解析:

  1. 创建 packaged_task

    • std::packaged_task<int(int)> task(square); 创建一个 packaged_task,该任务包装了 square 函数,函数的返回值类型为 int,接受一个 int 参数。
  2. 获取 future 对象

    • std::future<int> result = task.get_future(); 获取与 packaged_task 关联的 std::future 对象,未来可以通过该 future 来获取任务的结果。
  3. 异步执行任务

    • std::thread t(std::move(task), 5); 创建一个线程并异步执行任务,传递参数 5square 函数。
  4. 等待结果

    • result.get() 用于获取任务的结果。这会阻塞主线程,直到任务完成并返回值。
  5. 分离线程

    • t.detach(); 分离线程,让任务在后台运行,主线程继续执行。

3. 使用 Lambda 表达式与 std::packaged_task

你可以使用 Lambda 表达式来包装任务:

#include <iostream>
#include <future>
#include <thread>

int main() {
    // 使用 lambda 表达式创建 packaged_task
    std::packaged_task<int(int, int)> task([](int a, int b) {
        return a + b;
    });

    // 获取 future 对象
    std::future<int> result = task.get_future();

    // 在新线程中异步执行
    std::thread t(std::move(task), 10, 20);
    t.detach();

    // 等待结果
    std::cout << "The result is: " << result.get() << std::endl;

    return 0;
}

在这个例子中,Lambda 表达式 [ ](int a, int b) { return a + b; } 被传递给 packaged_task,并在新线程中执行,主线程通过 result.get() 获取任务的返回值。

std::packaged_task 的常用成员函数

  • get_future()
    获取与 packaged_task 关联的 std::future 对象,用于获取异步任务的结果。

  • operator()
    调用 packaged_task,执行其中的任务。可以通过在新的线程中调用 std::move(task) 来异步执行。

  • 构造函数
    包装一个可调用对象,允许异步调用并获取返回结果。

std::asyncstd::thread 的区别

  • std::packaged_taskstd::future
    std::packaged_taskstd::future 联合使用时,更加灵活,能够包装任意可调用对象并传递给线程或异步任务,用户可以显式控制任务的启动时间。

  • std::async
    std::async 自动将任务放在后台线程中执行,返回 std::future,适合快速执行简单的异步任务,但不如 packaged_task 灵活。

  • std::thread
    std::thread 只是单纯的启动一个线程,无法直接获取线程执行的返回结果。而 std::packaged_task 能与 std::future 结合,使得结果可以通过 future 在主线程中获取。

总结

  • std::packaged_task 用于包装一个可调用对象,使其可以异步执行,并通过 std::future 获取其返回值。
  • std::packaged_task 适合在异步任务管理中灵活控制任务的执行,与 std::futurestd::threadstd::async 配合使用时能够轻松管理异步操作。

标签:std,异步,task,packaged,future,线程
From: https://www.cnblogs.com/niumachen/p/18449883

相关文章

  • std::make_shared
    std::make_shared是C++11引入的一个标准库函数,用于创建一个std::shared_ptr,并在堆上分配所需的对象。它的功能是将对象的创建和shared_ptr的初始化合并在一起,提高了效率和安全性。使用方法:autoptr=std::make_shared<T>(args...);T:共享指针所管理的对象的类型。a......
  • `std::packaged_task`、`std::thread` 和 `std::async` 的区别与联系
    std::packaged_task、std::thread和std::async的区别与联系std::packaged_task、std::thread和std::async都是C++11中提供的并发工具,用于执行任务并处理多线程操作。虽然它们都有类似的作用(并发执行任务),但在功能和使用方式上有显著区别。下面分别解释它们的特点,并说明它......
  • std::unique_lock
    std::unique_lock是C++11标准库中的一个类,提供了一种灵活的方式来管理互斥量(mutex)。它比std::lock_guard更加灵活,允许在不同的作用域和不同的锁定策略之间进行选择。以下是对unique_lock的详细解释,包括其用途、使用方法和优点。1.定义std::unique_lock是一种RAII(资......
  • TaskMatrix
    TaskMatrixhttps://github.com/chenfei-wu/TaskMatrixTaskMatrixTaskMatrixconnectsChatGPTandaseriesofVisualFoundationModelstoenablesendingandreceivingimagesduringchatting. Insight&Goal:Ontheonehand,ChatGPT(orLLMs)serv......
  • freeRTOS源码解析4--tasks.c 7
    4.2.20空闲任务调用1--prvCheckTasksWaitingTermination删除所有终止的任务,释放资源。简单描述就是清空xTasksWaitingTermination列表,释放资源,递减uxCurrentNumberOfTasks和uxDeletedTasksWaitingCleanUp。接口:staticvoidprvCheckTasksWaitingTermination(void)接口代码如......
  • stdio流缓冲区
    文件流缓冲区每个进程都各自维护一个文件流表,和文件描述符表类似,并且这些文件流都有自己对应的缓冲区缓冲区的设计就是为了减少磁盘io,加快io的速度缓冲区模式通过setvbuf或者setbuf两个函数设置缓冲区的模式无缓冲区就是禁用缓冲区的意思,这种模式下,就相当于直接调用write函......
  • WPF Calendar DisplayMode SelectionMode FirstDayOfWeek Start End BlackoutDates
    //xaml<Windowx:Class="WpfApp427.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.mi......
  • android开发Execution failed for task ':bundleDebugAar'...Direct local .aar file
    1.问题描述[+103ms]FAILURE:Buildfailedwithanexception.[]*Whatwentwrong:[]Executionfailedfortask':jpush_flutter:bundleDebugAar'.[]>Errorwhileevaluatingproperty'hasLocalAarDeps'oftask......
  • Unity编辑器扩展-基于UniTask的Http请求和下载
    publicclassHttpHelper{publicstaticasyncUniTask<(bool,string)>RequestGetUrlAsync(stringurl,booldebug=false){Debug.Log($"reqgeturl:{url}");UnityWebRequestreq=null;......
  • C# Task若干问题浅析
    场景:分析数据库的表结构,并将表结构导出到word中。方案1.直接用UI线程做,由于会造成UI卡顿,忽略。方案2.用task:Taskts=Task.Run(()=>{for(inti=0;i<listTables.Count;i++){stringname=listTables[i].Name;List<SqlserverTableStru......