首页 > 其他分享 >`std::packaged_task`、`std::thread` 和 `std::async` 的区别与联系

`std::packaged_task`、`std::thread` 和 `std::async` 的区别与联系

时间:2024-10-06 18:01:44浏览次数:8  
标签:std task thread 任务 线程 async 执行

std::packaged_taskstd::threadstd::async 的区别与联系

std::packaged_taskstd::threadstd::async 都是 C++11 中提供的并发工具,用于执行任务并处理多线程操作。虽然它们都有类似的作用(并发执行任务),但在功能和使用方式上有显著区别。下面分别解释它们的特点,并说明它们的区别与联系。


1. std::packaged_task

特点

  • 封装可调用对象std::packaged_task 能将一个可调用对象(如函数、lambda、函数对象)包装起来,使其能够异步执行。
  • 返回结果:与任务关联的 std::future 对象可以通过 get() 方法获取任务的执行结果。
  • 任务执行方式std::packaged_task 本身不负责执行任务,它只是一个包装器,任务的实际执行需要通过线程、std::async 或直接调用。

使用场景

  • 适用于你想自己控制任务的执行过程,并且希望能够获得任务的返回值。std::packaged_task 提供了一种灵活的方式来包装任务,然后在不同的线程中执行它。

示例

std::packaged_task<int(int)> task([](int x) { return x * x; });
std::future<int> result = task.get_future();

// 通过线程执行任务
std::thread t(std::move(task), 10);
t.join();
std::cout << "Result: " << result.get() << std::endl;  // 输出: Result: 100

2. std::thread

特点

  • 手动管理线程std::thread 是最基础的并发工具,用于创建并管理一个线程。你可以将任何可调用对象传递给线程,在线程中并发执行。
  • 生命周期管理:线程的生命周期需要手动管理。你需要确保线程完成后调用 join()(等待线程结束)或 detach()(分离线程)。
  • 不返回结果std::thread 只负责启动一个新线程,它本身没有机制直接返回线程执行的结果。如果需要返回结果,你需要配合 std::future 或其他同步机制使用。

使用场景

  • 适用于你希望直接管理线程的创建、执行和结束过程的场景。std::thread 提供了底层的并发控制能力。

示例

std::thread t([] {
    std::cout << "Hello from thread!" << std::endl;
});
t.join();  // 等待线程执行完毕

3. std::async

特点

  • 简化异步任务执行std::async 用于异步执行任务。它自动管理线程的启动、执行和返回结果。
  • 返回结果std::async 返回一个 std::future 对象,允许你通过 future.get() 获取任务执行的结果。
  • 可选择异步或同步std::async 可以选择是否启动一个新线程(std::launch::async)或延迟执行(std::launch::deferred)。
  • 自动管理:与 std::thread 不同,std::async 不需要手动 join()detach(),它会自动管理任务的执行和资源回收。

使用场景

  • 适用于你希望将任务提交给系统自动管理,并且无需手动控制线程的场景。std::async 提供了高层次的异步任务管理功能。

示例

auto result = std::async([](int x) { return x * x; }, 10);
std::cout << "Result: " << result.get() << std::endl;  // 输出: Result: 100

总结区别

特性 std::packaged_task std::thread std::async
任务封装 通过 packaged_task 包装可调用对象 将可调用对象传递给线程直接执行 提交任务,系统自动决定如何执行
返回结果 通过 std::future 获取结果 不提供直接的返回机制 返回 std::future,自动管理任务返回值
线程管理 需要手动启动线程来执行任务 需要手动创建、管理、结束线程 自动管理任务执行,提供异步和同步模式
资源管理 任务执行和线程生命周期分开管理 需要显式 join()detach() 线程 自动管理资源,任务结束后自动回收资源
使用场景 灵活包装任务,控制任务执行过程 直接管理线程的生命周期和执行 简化的异步任务执行方式

通俗解释:

  • std::packaged_task:像打包一个任务的“快递包裹”,让你可以把任务交给别人(例如线程)去执行,然后你可以用“包裹单号”(std::future)去查询结果。
  • std::thread:是“直接开车送快递”,你自己负责启动这个“车”(线程),并且需要决定什么时候让车停下来(join())或让车继续开(detach())。
  • std::async:就像是找个“跑腿服务”,你把任务提交给跑腿系统,它会决定找人去做任务,并且在任务完成后,你可以直接通过“跑腿结果”(std::future)拿到结果。你不需要担心“车子”(线程)的管理。

标签:std,task,thread,任务,线程,async,执行
From: https://www.cnblogs.com/niumachen/p/18449241

相关文章

  • 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)接口代码如......
  • 【国产化】RT-THREAD ENV介绍和应用
    原创zgrxmmlinux源码阅读前言作为一款优秀的国产实时操作系统,RT-THREAD以其轻量级、高可靠性和丰富的生态系统,在众多嵌入式开发项目中崭露头角。今天,基于RT-THREAD探索如何利用其强大的ENV工具链快速搭建和配置STM32F429-ATK-APOLLO开发板的工程项目。通过这篇教程......
  • stdio流缓冲区
    文件流缓冲区每个进程都各自维护一个文件流表,和文件描述符表类似,并且这些文件流都有自己对应的缓冲区缓冲区的设计就是为了减少磁盘io,加快io的速度缓冲区模式通过setvbuf或者setbuf两个函数设置缓冲区的模式无缓冲区就是禁用缓冲区的意思,这种模式下,就相当于直接调用write函......
  • 【多线程奇妙屋】 Java 的 Thread类必会小技巧,教你如何用多种方式快速创建线程,学并发
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......
  • 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......
  • 【linux】linux unable to create new native thread
    1.概述今天遇到一个问题unabletocreatenewnativethread但是看着代码这里应该不会报错,出现这个问题该怎么排查呢?当在Linux系统中出现“unabletocreatenewnativethread”错误时,通常是由于达到了系统可用的进程或线程数量限制导致的。这个错误表示系统无法......
  • Unity编辑器扩展-基于UniTask的Http请求和下载
    publicclassHttpHelper{publicstaticasyncUniTask<(bool,string)>RequestGetUrlAsync(stringurl,booldebug=false){Debug.Log($"reqgeturl:{url}");UnityWebRequestreq=null;......