首页 > 编程语言 >C++异步编程

C++异步编程

时间:2023-12-01 12:44:52浏览次数:42  
标签:std 异步 task 编程 调用 C++ future 线程 promise

关键词
//都会返回一个std::future,用来提供执行结果
std::async、std::paclaged_task、std::promise
知识点
1、std::future<>():
a).std::future的临时对象在调用析构函数时会阻塞当前线程。注意在局部区域内的std::future的析构。
b).std::future::get()std::future::wait()同样会阻塞当前线程。
2、std::async:
a).当调用std::future::get()会阻塞当前线程,知道得到结果。
b).当调用std::async(fun*)时,未必会在新的线程中执行,若明确要在新线程中执行,可以使用std::launch::async参数如:std::async(std::launch::async,func*);强制在新线程中执行。
3、std::pack_task:
a).自身不定义函数,可以包装其他函数,可以配合在新的std::thread中使用如下:
#include <iostream>
#include <future>
#include <thread>

//定义函数
auto fun = [](int value) {
std::this_thread::sleep_for(std::chrono::seconds(5)); //睡眠5s后返回结果
return 100 + value;
};
//创建仿函数(包装函数)
std::packaged_task<int(int)> pk_task{fun};
//定义仿函数返回值返回于何处
std::future<int> f = pk_task.get_future();

//配合线程正式调用,使用move来实现右值引用,后面跟``着需要的传参
std::thread t1(std::move(pk_task), 20);

int main(){
//获取结果参数
std::cout << f.get() << std::endl;
//确定thread的加入方式
t1.join();
}
b).调用仿函数的方式有两种:
1、显式调用(直接调用),如上定义了pk_task伪函数,则可以:pk_task(10)进行直接调用,而后使用std::future::get()得到期值。
2).异步调用,如a)中一样,通过移动语句把pk_task(10)的控制权交给新线程,并开始执行,但别忘了,线程需要joindetach,否则系统异常终止。
注意:执行pk_task等价于执行fun(10)

3、std::promise:
a).非常强大的机制。例如,你可以将一个值传递给新进程,而不需要任何额外的同步操作
b).具体作用就是许诺一个值,这个值时std::future类型,可以用std::promise::get_future()来许诺这个值,只有调用std::promise::set_value()时这个承诺才会兑现,并且具体调std::promise::get_future()的行为者才会执行。如下:
auto promissFun = [](std::future<int> fut) { std::this_thread::sleep_for(std::chrono::seconds(5)); //睡眠5s后返回结果 std::cout <<"ID: " << std::this_thread::get_id()<< std::endl; std::cout <<"get(): " << fut.get() << std::endl; };
std::promise<int> my_promise; std::thread t2(promissFun, my_promise.get_future());
//未调用std::future::set_value
//...进入promissFun函数中,执行到fut.get()时``会阻塞等待,直到set_value()设置
//调用std::future::set_value
my_promise.set_value(50);
//确定thread的加入方式
t2.join();

补充说明

标签:std,异步,task,编程,调用,C++,future,线程,promise
From: https://www.cnblogs.com/lvshen/p/17869098.html

相关文章

  • 实验四-现代C++标准库与类模板
    1#include<iostream>23usingstd::cout;4usingstd::endl;56classA{7public:8A(intx0,inty0):x{x0},y{y0}{}9voidshow()const{cout<<x<<","<<y<<endl;}10private:11......
  • C++20(信号量)
    #include<iostream>#include<semaphore>#include<thread>usingnamespacestd;std::counting_semaphore<3>csem(0);//semaphorerelease=condition_variablenotify//semaphoreacquire=condition_variablewaitvoidtask(){......
  • 你知道C++如何在一个函数内返回不同类型吗?
    C++中要在一个函数内返回不同类型的值,你可以使用C++17引入的std::variant或std::any,或者使用模板和多态。下面将分别介绍这些方法。方法一:使用std::variantstd::variant允许你在一个函数内返回不同类型的值,但它要求所有可能的返回类型都在一个有限的集合中,你需要提前定......
  • 实验四 现代C++标准库类与模板
    实验任务1task1.cpp源码task1_1.cpp:#include<iostream>usingstd::cout;usingstd::endl;//类A的定义classA{public:A(intx0,inty0):x{x0},y{y0}{}voidshow()const{cout<<x<<","<<y<<endl;}......
  • 实验4 现代C++标准库与类模板
    实验任务5textcoder.hpp#programonce#include<iostream>#include<string>usingnamespacestd;classTextCoder{private:stringtext;voidencoder();voiddecoder();public:TextCoder(string&str);stringget_ciphertext(......
  • 实验4 现代C++标准库与类模板
    实验任务51#include<iostream>2#include<string>3usingnamespacestd;4classTextCoder5{6public:7TextCoder()=default;8TextCoder(stringstr);9stringget_ciphertext();10stringget_deciphertext();11......
  • Linux Mint(Ubuntu)系统VS Code C/C++环境配置include error问题
    1.问题描述安装完成LinuxMint后发现随系统自带了gcc,心里比较开心,以为自己不需要装了。但是在安装完VSCode之后,一直提示#includeerrorsdetected.PleaseupdateyourincludePath.Squigglesaredisabledforthistranslationunitlinux2.解决方案重新通过apt安装gcc......
  • 实验4 现代c++标准库与类模板
    实验任务1task1.cpp源码task1_1.cpp:1#include<iostream>23usingstd::cout;4usingstd::endl;56//类A的定义7classA{8public:9A(intx0,inty0):x{x0},y{y0}{}10voidshow()const{cout<<x<<","<......
  • 实验四 现代c++ 标准库与类的模板
    1.普通数组、array、vector的相关性,以及,区别相关性存储多个元素:1.普通数组:使用C风格数组声明和定义,大小固定。2.array:是C++11引入的标准库容器,提供了数组的替代,大小固定。3.vector:是C++标准库中的动态数组,大小可以动态调整。元素访问:1.普通数组和array:使用索......
  • C++ 泛型编程之可变参数包
    C++泛型编程之可变模板参数·variadictemplates可以表示0到任意个数、任意类型的参数1.可变模板参数的展开:template<typename...Args> //可以将参数包展开一个个独立的参数voidfunc(Args...args); //声明一个参数包Args...args这个参数包可以包括0到任意个模板参数......