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

news/2024/10/20 15:46:39/

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.ppmy.cn/news/1069295.html

相关文章

Linux操作系统--shell编程(read读取控制台输入)

1.基本语法 read (选项) (参数) 选项: -p:指定读取值时的提示符; -t:指定读取值时等待的时间(秒)如果-t 不加表示一直等待 参数: 变量:指定读取值的变量名

纯 CSS 开关切换按钮

<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>纯 CSS 开关切换按钮</title><style>html {font-size: 62.5%;}body {background-color: #1848a0;}.wrapper {position: absolute;left: …

SpringBoot整合 redis key (过期、新增、修改)的三种方式,看这篇就够了

文章目录 原理关于 *notify-keyspace-events*关于redis的消息主题&#xff08;Topic&#xff09;重写监听容器注册自定义解析常见整合问题鸣谢 文章主要描述了Springboot整合key变化的三种方式&#xff0c;同时列出了一些整合坑点与概念 原理 SpringBoot整合Redis key变化的原…

JVM 访问对象的两种方式

Java 程序会通过栈上的 reference 数据来操作堆上的具体对象。由于 reference 类型在《Java 虚拟机规范》里面只规定了它是一个指向对象的引用&#xff0c;并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置&#xff0c;所以对象访问方式也是由虚拟机实现而…

数据库第十七课-------ETL任务调度系统的安装和使用

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

②matlab桌面和编辑器

目录 matlab编辑器练习 运行脚本 matlab编辑器练习 您可以通过点击灰色代码框在脚本中输入命令。 准备就绪后&#xff0c;您可以通过点击蓝色的提交按钮提交代码。 任务 在脚本中输入命令 r 3。 2.任务 在脚本中添加命令 x pi*r^2。 附加练习 当您在实时编辑器中完成…

排序算法-选择排序(Java)

选择排序 选择排序 &#xff08;selection sort&#xff09;的工作原理非常直接&#xff1a;开启一个循环&#xff0c;每轮从未排序区间选择最小的元素&#xff0c;将其放到已排序区间的末尾。 算法原理 排序数组&#xff1a;&#xff08;2 4 3 1 5 2&#xff09; &#xf…

pyqt5-快捷键QShortcut

import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import *""" 下面示例揭示了&#xff0c;当关键字绑定的控件出现的时候&#xff0c;快捷键才管用&#xff0c; 绑定的控件没有出现的时候快捷键无效 """…