C++ 异步编程(std::async、std::future、std::promise)

devtools/2024/10/21 7:45:05/

C++ 11 异步编程

std::thread (C++创建线程)

函数
thread() noexcept创建一个线程,什么也不做
template <class Fn, class… Args>
explicit thread(Fn&& fn, Args&&… args)创建一个线程,以args为参数,执行fn函数
thread(const thread&) = delete复制购置函数
thread(thread&& x) noexcept移动购置函数
~thread()析构函数
void join()等待线程结束并清理资源(会阻塞)
bool joinable()返回线程是否可以joinable
void detach()将线程与调用其的线程分离,彼此独立执行(此函数必须在线程创建时立即调用,且调用此函数会使其不能被join)
thread& operator=(thread &&rhs)移动赋值函数

例子:

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
std::mutex mtx;
void thread_p(int a, int b)
{mtx.lock();cout <<"thread id:"<< std::this_thread::get_id()<< " a:" << a << "b: " << endl;mtx.unlock();
}
int main()
{std::thread t1(thread_p, 1,2), t2(thread_p, 3,4);cout << "t1.joinabel(): " << t1.joinable()<<endl;t1.join();cout << "t1.joinabel(): " << t1.joinable() << endl;t2.detach();cout << "t2.joinabel(): " << t2.joinable() << endl;return 0;
}

运行结果:
在这里插入图片描述

std::future

thread对象,它是C++11中提供异步创建多线程的工具。但是我们想要从线程中返回异步任务结果,一般需要依靠全局变量;从安全角度看,有些不妥;为此C++11提供了std::future类模板,future对象提供访问异步操作结果的机制,很轻松解决从异步任务中返回结果。
参考
https://en.cppreference.com/w/cpp/thread/future

函数解释
void wait() const;等待值返回
template< class Rep, class Period >std::future_status wait_for( const std::chrono::duration<Rep,Period>& timeout_duration ) const;等待多长时间
template< class Clock, class Duration >std::future_status wait_until( const std::chrono::time_point<Clock,Duration>& timeout_time ) const;等待到多久之后返回
get会一直阻塞直到拿到结果
bool valid() const noexcept;检查 future 是否引用共享状态。
#include <iostream>
#include <future>
#include <thread>
using namespace std;
int main()
{std::future<int> f;cout << f.valid() << endl;std::future<int> v = std::async([] {std::this_thread::sleep_for(std::chrono::milliseconds(1000)); return 8; });std::future_status status = v.wait_for(std::chrono::microseconds(2000));switch (status){case std::future_status::deferred:std::cout << "deferred\n";break;case std::future_status::timeout:std::cout << "timeout\n";break;case std::future_status::ready:std::cout << "ready!\n";break;}cout << v.valid() << endl;cout << v.get() << endl;cout << v.valid() << endl;return 0;
}

在这里插入图片描述

std::promise

std::promise 是C++11并发编程中常用的一个类,常配合std::future使用。其作用是在一个线程t1中保存一个类型typename T的值,可供相绑定的std::future对象在另一线程t2中获取。
https://en.cppreference.com/w/cpp/thread/promise

函数
get_future获取一个futrue对象
set_value设置值
#include <iostream>
#include <future>void thread1(std::promise<int> &p)
{std::this_thread::sleep_for(std::chrono::milliseconds(500));std::cout << "thread1 set data" << std::endl;p.set_value(1);
}void thread2(std::future<int>& p)
{int data = p.get();std::cout << "thead2 read data:" <<data << std::endl;
}
int main()
{using namespace std;std::promise<int> p;std::future<int> f = p.get_future();std::thread t1(thread1, std::ref(p));std::thread t2(thread2, std::ref(f));t1.join();t2.join();return 0;
}

结果:

在这里插入图片描述

std::async

由于std::thread不能很方便的获取线程运行完之后的返回值
https://en.cppreference.com/w/cpp/thread/async

template< class F, class… Args >/* see below */ async( F&& f, Args&&… args );立即执行
template< class F, class… Args >/* see below */ async( std::launch policy, F&& f, Args&&… args );可以设置延迟和立即执行状态
std::launch::async立即执行
std::launch::deferred延迟执行

不接收返回值会先阻塞

不接收放回值相当于std::thread语句后面立即join会阻塞当前线程执行完然后执行下一个线程。

#include <iostream>
#include <thread>
#include <future>
using namespace std;int main()
{std::async([] {for (int i = 0; i < 5; i++){cout << "thead 1:" << i<< endl;}});std::async([] {for (int i = 0; i < 5; i++){cout << "thead 2:" << i << endl;}});return 0;
}

在这里插入图片描述

接收返回值才不会直接阻塞

#include <iostream>
#include <thread>
#include <future>
using namespace std;int main()
{std::future<void> r1=  std::async([] {for (int i = 0; i < 5; i++){cout << "thead 1:" << i<< endl;}});std::async([] {for (int i = 0; i < 5; i++){cout << "thead 2:" << i << endl;}});return 0;
}

在这里插入图片描述

std::launch::deferred 延迟加载

只有当wait、get结果才会执行

#include <iostream>
#include <thread>
#include <future>
using namespace std;int main()
{std::future<void> r1=  std::async(std::launch::deferred,[] {for (int i = 0; i < 5; i++){cout << "thead 1:" << i<< endl;}});std::async([] {for (int i = 0; i < 5; i++){cout << "thead 2:" << i << endl;}});return 0;
}

在这里插入图片描述

#include <iostream>
#include <thread>
#include <future>
using namespace std;int main()
{std::future<void> r1=  std::async(std::launch::deferred,[] {for (int i = 0; i < 5; i++){cout << "thead 1:" << i<< endl;}});std::async([] {for (int i = 0; i < 5; i++){cout << "thead 2:" << i << endl;}});r1.get();return 0;
}

在这里插入图片描述

总结

std::future一个未来值,可以先赋值,来源可以是std::promise的set_value之后,或者是std::async的返回值
std::promise和std::future结合可以从一个线程中回去另一个线程的值。
std::async创建线程、需要获取返回值std::future对象,不然会直接阻塞。并且可以指定,std::launch::async立即执行std::launch::deferred延迟执行,延迟执行只有wait future对象或get future对象的之后才会执行

http://www.ppmy.cn/devtools/100728.html

相关文章

写论文找不到灵感?ChatGPT能提供的一些帮助

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 在学术写作过程中&#xff0c;许多读者常常会面临一个问题——找不到灵感。面对庞大的文献和复杂的研究方向&#xff0c;往往感到无从下手。随着人工智能技术的发展&#xff0c;像ChatG…

基于Springboot的多功能智能点餐小程序/基于微信小程序的点餐系统

摘要 计算机网络如果结合使用信息管理系统&#xff0c;能够提高管理员管理的效率&#xff0c;改善服务质量。优秀的智能点餐系统能够更有效管理用户智能点餐业务规范&#xff0c;帮助管理者更加有效管理用户智能点餐&#xff0c;可以帮助提高克服人工管理带来的错误等不利因素。…

数据可视化大屏模板-美化图表

Axure作为一款强大的原型设计软件&#xff0c;不仅擅长构建交互式界面&#xff0c;更在数据可视化方面展现出了非凡的创意与实用性。今天&#xff0c;就让我们一起探索Axure设计的几款精美数据可视化大屏模板&#xff0c;感受数据之美。 立体图表的视觉冲击力 Axure的数据可视…

Linux云计算 |【第二阶段】SECURITY-DAY2

主要内容&#xff1a; Zabbix报警机制&#xff08;创建触发器、设置邮箱、执行动作&#xff09;&#xff0c;Zabbix进阶操作&#xff08;主动发现、主被动监控模式、拓扑图、聚合图形&#xff09;、监控案例&#xff08;监控Nginx服务状态、监控TCP连接状态&#xff09; 一、Z…

若依将登录用户的userId自动加载到查询中

点击搜索&#xff0c;会将登录用户的userId作为搜索条件&#xff0c;去查询。 新版本自动存储了userId&#xff0c;我们不用改&#xff0c;只要知道如何引用。 前端使用 在对应的vue文件&#xff0c;查询queryParams 加查询的值 然后参考他的 添加store import store from &…

Linux基础知识(一、什么是Linux)

一、Linux之父——林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff09; Linux操作系统最初是在1991年10月份由芬兰赫尔辛基大学的在校生Linus Torvalds所发布,最初被发布的LINUX0.02版本因其高质量的代码与开放源代码&#xff0c;迅速引起了一大批黑客的加…

小琳AI课堂:使用ChatGPT API搭建系统(一)

大家好&#xff0c;这里是小琳AI课堂。今天我们来聊聊提示链的构建&#xff0c;这是一个非常有趣且实用的技术话题。提示链&#xff0c;简单来说&#xff0c;就是一系列逻辑上相互关联的提示&#xff0c;用于指导大型语言模型&#xff08;如ChatGPT API&#xff09;如何处理复杂…

服务器主动推送的方法

目录 1.长轮询&#xff08;Long Polling&#xff09;2.WebSockets3.Server-Sent Events&#xff08;SSE&#xff09;4.HTTP2 Server Push 服务器如何主动推送数据 在传统的网络通信中&#xff0c;客户端&#xff08;如浏览器&#xff09;通常需要通过向服务器发起请求来获取数据…