首页 > 编程语言 >C++多线程——async、packages_task、promise

C++多线程——async、packages_task、promise

时间:2023-10-30 19:45:12浏览次数:37  
标签:std task int C++ future 线程 promise 多线程

异步编程 asyncfuture


基本概念和使用:

  • 异步执行函数:std::async 可以异步执行一个函数,这意味着函数将在后台线程中执行,而当前线程可以继续执行其他任务。

  • 返回值获取:你可以获得函数的返回值,或者得到一个 std::future 对象,它允许你在将来的某个时刻获取函数的结果。

  • 线程池使用:具体的线程管理是由 C++ 标准库的实现来处理的,它可以使用线程池来执行函数,以提高性能和资源利用率。


一个简单的使用示例说明 std::async 的使用:


#include <iostream>
#include <future>

int add(int a, int b) {
    return a + b;
}

int main() {

    std::future<int> result = std::async(std::launch::async, add, 1, 2);

    // 执行一些其它函数

    // 获取函数的返回值
    int sum = result.get();

    std::cout << "sum = " << sum << std::endl;

    return 0;
}


  • 我们使用 std::launch::async 标记来显式请求在新线程中执行函数,但具体的线程管理是由标准库来处理的。

  • result.get() 用于获取异步执行函数的结果,是阻塞的。如果子线程没用计算完,会阻塞在这里。


packaged_task

C++11引入,将可调用对象(函数、函数指针、lambda表达式)包装为异步任务,并可以与期望对象std::future关联,从而获取异步执行的返回值。

主要用法:

  • 包装可调用对象:std::packaged_task 允许你将一个可调用对象(函数或函数对象)包装为一个任务。

  • 异步执行:你可以通过调用 std::packaged_task 对象的 operator() 方法在后台线程中执行包装的可调用对象。

  • 获取结果:std::packaged_task 与 std::future 结合使用,允许你在将来的某个时刻获取任务的执行结果。


举例使用packaged_task对可调用对象进行包装,后异步执行,返回结果:

#include <iostream>
#include <future>

int add(int a, int b) {
    return a + b;
}

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

    // 获取与任务相关联的 future
    std::future<int> result = task.get_future();

    // 异步执行任务
    std::thread t(std::move(task), 3, 4);

    // 执行一些其他工作...

    // 获取任务的执行结果
    int sum = result.get();

    t.join();

    std::cout << "Sum: " << sum << std::endl;

    return 0;
}


promise

std::promise 是一种用于在一个线程中生成一个结果,并在另外一个线程中获取结果的机制。std::promise 允许一个线程承诺(promise)一个值,并提供一个与之关联的 std::future,在另一个线程中可以通过 std::future 获取该值。

以下是 std::promise 的主要概念和用法:

  • 生成值:一个线程使用 std::promise 来生成一个值,可以是任何类型的数据(例如,整数、字符串、自定义结构等)。

  • 提供 std::future:std::promise 提供了一个 get_future() 方法,它返回一个与该 promise 关联的 std::future 对象,可以用于在其他线程中等待获取值。

  • 获取值:在另一个线程中,你可以使用与 promise 关联的 std::future 来等待获取值。一旦 promise 的值被设置,std::future 可以获取到该值。

以下示例说明使用promise设置值并获取值的过程:

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

void setValue(std::promise<int>& p) {
    std::this_thread::sleep_for(std::chrono::seconds (2));
    p.set_value(42);
}

int main() {

    std::promise<int> myPromise;

    std::future<int> res = myPromise.get_future();

    std::thread t(setValue, std::ref(myPromise));

    int value = res.get();

    t.join();

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

    return 0;
}

标签:std,task,int,C++,future,线程,promise,多线程
From: https://www.cnblogs.com/vLiion/p/17798622.html

相关文章

  • 深入理解多线程编程和 JVM 内存模型
    文章目录1.理解进程和线程的概念进程(Process)线程(Thread)2.理解竞态条件和死锁竞态条件(RaceCondition)死锁(Deadlock)3.JVM内存模型堆(Heap)栈(Stack)方法区(MethodArea)本地方法栈(NativeMethodStack)PC寄存器(ProgramCounterRegister)垃圾回收4.常见的多线程编程模式生产者-消费者......
  • C++多线程——线程池
    线程池ThreadPool线程池简单来说就是用来管理多个线程的,以避免频繁开辟或销毁线程的情况。以下是创建和使用线程池的基本步骤:创建一个任务队列,用于存储待执行的任务。创建一组线程,这些线程会从任务队列中获取任务并执行它们。将任务提交到任务队列中,由线程池的线程......
  • 在多线程里面,为什么推荐使用notifyAll而不是notify
    在多线程里面,为什么推荐使用notifyAll而不是notify?结论:notify容易造成死锁1、无论使用notify或者notifyAll,都是随机唤醒线程2、notify是随机唤醒一个线程去执行,noifyAll是唤醒所有线程,然后去抢占锁,去执行怎么产生死锁现象:P–生产者调用putproductC–消费者调用c......
  • Tornado实现多线程/多进程的HTTP服务
    用tornadoweb服务的基本流程原文链接1.实现处理请求的Handler,该类继承自tornado.web.RequestHandler,实现用于请求的对应方法如:get,post等。返回内容用self.write方法输出。**2.实例化一个Application。**构造函数的参数是一个Handler列表,通过正则表达式,将请求与Handler对应起来......
  • C++U4-02-贪心算法2
    上节课作业部分  [纪念品分组]  【算法分析】贪心算法:先对数组从小到大排序,用l=1,r=n指针指向首尾元素;如果pl+pr≤w,则将pl和pr分一组,指针l++,r--。如果pl+pr>w,则将pr单独作为一组,指针r--。如此反复直到取完所有元素。#include<iostream>#include<a......
  • C++U5-深度优先搜索-03(记忆化搜索、剪枝和优化)
    ......
  • C++23:多维视图(std::mdspan)
    C++23:多维视图(std::mdspan)介绍在C++23中,std::mdspan是一个非拥有的多维视图,用于表示连续对象序列。这个连续对象序列可以是一个简单的C数组、带有大小的指针、std::array、std::vector或std::string。这种多维视图通常被称为多维数组。多维数组的形状由其维数(也称为秩)和每个......
  • C++中低级内存操作
    C++中低级内存操作C++相较于C有一个巨大的优势,那就是你不需要过多地担心内存管理。如果你使用面向对象的编程方式,你只需要确保每个独立的类都能妥善地管理自己的内存。通过构造和析构,编译器会帮助你管理内存,告诉你什么时候需要进行内存操作。将内存管理隐藏在类中显著提高了可用性,......
  • 排序算法:选择排序,分别用c++、java、python实现
    选择排序介绍选择排序(SelectionSort)是一种简单的比较排序算法,它的工作原理如下:分区:将待排序的数组分成两个部分,一个部分是已排序的子数组,另一个部分是未排序的子数组。初始时,已排序的子数组为空,而未排序的子数组包含整个数组。选择最小值:从未排序的子数组中找到最小(或最大,根据......
  • 算法题:分别用c++/python/java实现回文数
    回文数是一个数字,从左到右和从右到左读都是相同的数字序列。换句话说,回文数在数值上是对称的。一些常见的回文数示例包括:单个数字:例如1、2、3等,它们本身就是回文数,因为它们只有一个数字。两位数:例如11、22、33等,它们也是回文数,因为它们的左右两个数字相同。多位数:例如121、1331、12......