c++多线程中常用的使用方法

1)promise(保证)和future的联合使用,实现两个线程的数据传递

#include <iostream>
#include<thread>
#include<future>using namespace std;//promise用法:可以给线程一个值,而从另一个线程读出该值
// 实现了两个线程的数据传递!
void myPromise(std::promise<int>& tmp,int num)//promise线程
{//在这里假使处理复杂的计算,最后得出一个值,并返回num = num + 20;tmp.set_value(num);
}//另一个线程可以得到promise计算后得到的值
void myFuture(std::future<int>& tmp)
{cout<<"myFuture thread receive value is : "<< tmp.get()<<endl;
}int main()
{std::promise<int> pro;std::thread th1(myPromise,std::ref(pro),10); //创建promise线程时,第二个参数一定要用引用th1.join();std::future<int> result = pro.get_future();std::thread th2(myFuture,std::ref(result));  //std::ref( pro.get_future())用临时对象不可以;th2.join();return 0;
}

//输出结果:myFuture thread receive value is : 30
2) package_task的使用,把任务从新包装起来,案例代码如下:

#include <iostream>
#include<thread>
#include<future>using namespace std;int func(void)
{cout<<"start----- thread_id is : "<<std::this_thread::get_id()<<endl;std::this_thread::sleep_for(std::chrono::milliseconds(2000));cout<<"end-------- thread_id is : "<<std::this_thread::get_id()<<endl;return 5;
}//package_task类模板,可以包装任何可调用对象
int main()
{std::packaged_task<int()> task(func);std::thread th(std::ref(task)); //package_task里面有一个成员函数get_future(),可以返回一个future对象;th.join();std::future<int> result = task.get_future();cout<<result.get()<<endl;return 0;
}

3)//std::async和std::future一起配合使用

#include <iostream>
#include<thread>
#include<mutex>
#include<list>
#include<future>// std::async和std::future的用法:
// async是一个函数模板,启动一个线程;std::future是类模板,当async启动任务后,会返回std::future对象;
// std::future对象里面有需要的返回值;
using namespace std;int func(void)
{cout<<"start----- thread_id is : "<<std::this_thread::get_id()<<endl;std::this_thread::sleep_for(std::chrono::milliseconds(2000));cout<<"end-------- thread_id is : "<<std::this_thread::get_id()<<endl;return 5;
}//std::launch::deferred参数时,等待wait或者get返回,如果没有这两个函数,直接运行接下来代码
//std::launch::deferred参数不会创建新线程!!!
//std::future两个成员函数,get是等待线程处理完返回结果;wait是等待线程处理完,不返回结果
int main()
{cout<<"main thread start----- thread_id is : "<<std::this_thread::get_id()<<endl;std::future<int> result = std::async(func); //程序不会卡到这里!!!这里存在一个绑定关系cout<<"********main run*********"<<endl;cout<<result.get()<<endl; //程序会卡到这里,等待线程返回结果(利用的是std::future的成员函数get)return 0;
}

4)//条件变量与互斥量的配合使用方法:

#include <iostream>
#include<thread>
#include<mutex>
#include<list>
#include<condition_variable>
//条件变量是和互斥量配合使用!using namespace std;class A{
public:void inQueue(void){for(int i = 0; i<10000;i++){cout<<"insert message : "<<i<<endl;{std::unique_lock<std::mutex> uniqueLock(mtx); message.push_back(i);cond.notify_one();}}}void outQueue(void){for(int i = 0 ; i<10000; i++){std::unique_lock<std::mutex> uniqueLock(mtx); //自动加锁//wait跟互斥量的关系:wait阻塞解锁,wait唤醒加锁!!!cond.wait(uniqueLock,[this](){ //如果参数2是false,解锁等待;如果是true,加锁完成后,继续执行下面代码if(!message.empty()) return true;elsereturn false; //可以处理虚假唤醒,就是说容器没有数据,但被唤醒了,执行解锁等待。});       int cmd = message.front();message.pop_front();             cout<<"out cmd---------- is :"<<cmd<<endl;     }//出作用域,uniqueLock锁释放;}
private:std::list<int> message;std::condition_variable cond;std::mutex mtx;};int main()
{A a;std::thread th1(&A::inQueue,&a);std::thread th2(&A::outQueue,&a);th1.join();th2.join();return 0;
}

5)互斥量的使用方法:

#include <iostream>
#include<thread>
#include<mutex>
#include<list>
#include<condition_variable>using namespace std;class A{
public:void inQueue(void){for(int i = 0; i<10000;i++){cout<<"insert message : "<<i<<endl;{std::unique_lock<std::mutex> uniqueLock(mtx); message.push_back(i);}std::this_thread::sleep_for(std::chrono::milliseconds(1));}}void outQueue(void){for(int i = 0; i<10000;i++){if(!message.empty()){int cmd = 0;{std::unique_lock<std::mutex> uniqueLock(mtx); cmd = message.front();message.pop_front();}cout<<"out cmd is :"<<cmd<<endl;}else{cout<<"empty---------------i: "<<i<<endl;}std::this_thread::sleep_for(std::chrono::milliseconds(1));}}
private:std::list<int> message;std::mutex mtx;};int main()
{A a;std::thread th1(&A::inQueue,&a);std::thread th2(&A::outQueue,&a);th1.join();th2.join();return 0;
}

6)单例模式在线程中的使用

#include <iostream>
#include<thread>
#include<mutex>using namespace std;std::mutex mtxRes;
//单例目的:即使多个线程被创建,也要保证只创建一个对象,所以创建多线程创建对象时,要做互斥量条件判断!!!
class A
{
private:A(){cout<<"A conctructor---"<<endl;}
private:static A* m_instance; //声明一个静态私有类指针变量
public:static A* getInstance(){if(m_instance == nullptr) //多个线程,为了提升速度(双重锁定){std::unique_lock<std::mutex> uniquelock(mtxRes);if(m_instance == nullptr){m_instance = new A();static garb cl;//为了程序退出后,能够正常删除m_instance}}return m_instance;}void test(void){cout<<"test------"<<endl;}class garb //为了能正常delete m_instance,而设计的内部类{public:~garb(){if(A::m_instance != nullptr){delete A::m_instance;A::m_instance = nullptr;}}};
};A* A::m_instance = nullptr;void func(void)
{cout<<"-----开始单例模式创建--------"<<endl;A::getInstance()->test();cout<<"-----单例模式创建完成--------"<<endl;
}int main()
{// A::getInstance()->test();std::thread th1(func);std::thread th2(func);        th1.join();th2.join();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/57993.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flink常用函数

1、比较函数 <> > > < < 注意&#xff1a;select nullnull; 返回为nullIS NULL 、 IS NOT NULL --非空判断value1 IS DISTINCT FROM value2、value1 IS NOT DISTINCT FROM value2、 --不同于value1 BETWEEN [ ASYMMETRIC | S OR 、AND、NOT boolean…

VMware虚拟机---Ubuntu无法连接网络该怎么解决?

在学习使用Linux系统时&#xff0c;由于多数同学们的PC上多是Windows系统&#xff0c;故会选择使用VMware创建一个虚拟机来安装Linux系统进行学习。 安装完成之后&#xff0c;在使用时总是会遇到各种各样的问题。本片随笔就主要针对可能出现的网络问题进行一个总结&#xff0c;…

物种气候生态位动态量化与分布特征模拟

在全球气候快速变化的背景下&#xff0c;理解并预测生物种群如何应对气候变化&#xff0c;特别是它们的地理分布如何变化&#xff0c;已经变得至关重要。利用R语言进行物种气候生态位动态量化与分布特征模拟&#xff0c;不仅可以量化描述物种对环境的需求和适应性&#xff0c;预…

限流算法深入

限流定义及目的 当系统流量达到系统或下游承受能力的阈值时对系统进行限流控制以防止系统或下游挂掉&#xff0c;减少影响面。 限流组成&#xff1a;阈值及限流策略。阈值是指系统单位时间接收到的请求qps总数&#xff1b;限流策略是指限流行业触发后对应的系统行为&#xff…

FPGA GTX全网最细讲解,aurora 8b/10b协议,HDMI板对板视频传输,提供2套工程源码和技术支持

目录 1、前言免责声明 2、我这里已有的 GT 高速接口解决方案3、GTX 全网最细解读GTX 基本结构GTX 发送和接收处理流程GTX 的参考时钟GTX 发送接口GTX 接收接口GTX IP核调用和使用 4、设计思路框架视频源选择IT6802解码芯片配置及采集动态彩条视频数据组包GTX aurora 8b/10b数据…

Django(5)-视图函数和模板渲染

Django 中的视图的概念是「一类具有相同功能和模板的网页的集合」 在我们的投票应用中&#xff0c;我们需要下列几个视图&#xff1a; 问题索引页——展示最近的几个投票问题。 问题详情页——展示某个投票的问题和不带结果的选项列表。 问题结果页——展示某个投票的结果。 投…

SVN 项目管理笔记

SVN 项目管理笔记 主要是介绍 SVN 管理项目的常用操作&#xff0c;方便以后查阅&#xff01;&#xff01;&#xff01; 一、本地项目提交到SVN流程 在SVN仓库下创建和项目名同样的文件夹目录&#xff1b;选中本地项目文件&#xff0c;选择SVN->checkout,第一个是远程仓库项…

大数据Flink实时计算技术

1、架构 2、应用场景 Flink 功能强大&#xff0c;支持开发和运行多种不同种类的应用程序。它的主要特性包括&#xff1a;批流一体化、精密的状态管理、事件时间支持以及精确一次的状态一致性保障等。在启用高可用选项的情况下&#xff0c;它不存在单点失效问题。事实证明&#…

vue 学习笔记 简单实验

1.代码(html) <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"counter">Counter: {{ counter }} </div> <script> const Counter {data() {return {counter: 5}} } Vue.cr…

java-便签

--其实最痛的。不是离别。而是离别后的那些回忆。 java length( ) javalength中文占多长 1.一个中文字符或符号 2 个字节&#xff0c;一个英文字符或符号 1 个字节。 System.out.println("abc你好&#xff0c;".getBytes("gbk").length); System.out.pr…

【Linux】【驱动】驱动挂载的时候给驱动传递参数

【Linux】【驱动】驱动挂载的时候给驱动传递参数 绪论1.什么是驱动传参驱动传参就是传递参数给我们的驱动举例:2.驱动传参数有什么作用呢?3. 传递单个参数使用如下的数组4. 传递数组使用以下函数&#xff1a; 传递数字值代码指令 传递数组代码传递数组指令 绪论 1.什么是驱动…

C语言(第二十九天)

1.2.2 文件结构设计 之前学习了多文件的形式对函数的声明和定义&#xff0c;这里我们实践一下&#xff0c;我们设计三个文件&#xff1a; test.c //文件中写游戏的测试逻辑 game.c //文件中写游戏中函数的实现等 game.h //文件中写游戏需要的数据类型和函数声明等 2. 扫雷游戏的…

如何拼接两个视频在一起?

如何拼接两个视频在一起&#xff1f;在度过一个美好周末的时候&#xff0c;我和朋友一起拍摄了两组视频&#xff0c;准备将两个视频合并成一个并发布到朋友圈。这个想法非常棒&#xff0c;但是我在第一步就遇到了麻烦&#xff1a;如何将这两个视频拼接在一起&#xff1f;这听起…

Go 自学:struct结构体

以下代码展示如何建立一个结构体struct。 我们可以使用%v查看结构体的详情。 package mainimport ("fmt" )func main() {Jeff : User{"Jeff", "Jeffgo.dev", true, 16}fmt.Println((Jeff))fmt.Printf("Jeff details are: %v\n", Jeff…

7天GMV达220万美元!TikTok Shop爆品榜出炉。

7天GMV达220万美元&#xff01;TikTok Shop爆品榜出炉 8月28日消息&#xff0c;据跨境指南联合TikTok数据分析平台EchoTik发布的数据&#xff0c;监测了上周TikTok Shop印尼、马来西亚、泰国、美国市场GMV前10的商品。上周在印尼市场GMV排名前10的商品中&#xff1a;FREE ONGK…

RPA是什么样的机器人技术?RPA可以实现哪些流程的自动化?

一、RPA是什么样的机器人技术&#xff1f; RPA&#xff08;Robotic Process Automation&#xff09;即机器人流程自动化&#xff0c;是一种通过模拟人类在计算机系统上的操作&#xff0c;实现流程自动化的技术。RPA机器人可以代替人工执行各种重复性任务&#xff0c;如数据输入…

基于微服务、Java、Springcloud、Vue、MySQL开发的智慧工地管理系统源码

智慧工地聚焦施工现场岗位一线&#xff0c;围绕“人、机、料、法、环”五大要素&#xff0c;数字化工地平台与现场多个子系统的互联实现了工地业务间的互联互通和协同共享。数字化工地管理平台能够盘活工地各大项目之间孤立的信息系统&#xff0c;实现数据的统一接入、处理与维…

【Spring Boot】Spring Boot实现完整论坛功能示例代码

以下是一个简单的Spring Boot论坛系统示例代码&#xff1a; 首先是数据库设计&#xff0c;我们创建以下几张表&#xff1a; user表&#xff0c;存储用户信息&#xff0c;包括id、username、password、email、create_time等字段。topic表&#xff0c;存储帖子信息&#xff0c;…

迅睿系统二开自定义函数和插件的自定义函数

全局的自定义函数&#xff1a; 全局的自定义函数文件&#xff1a;dayrui/My/Helper.php 此文件用于放网站自定义函数&#xff0c;程序会自动加载 当前站点的自定义函数文件&#xff1a;网站主目录/config/custom.php 插件的自定义函数&#xff1a; 基于App目录下的插件或模块…

辉瑞乡村振兴战略下传统村落文化旅游设计小红书中美德少许

辉瑞乡村振兴战略下传统村落文化旅游设计小红书中美德少许