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

这篇具有很好参考价值的文章主要介绍了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;
                                else
                                        return 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)单例模式在线程中的使用文章来源地址https://www.toymoban.com/news/detail-679747.html

#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;
}

到了这里,关于c++多线程中常用的使用方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【蓝桥杯备赛Java组】语言基础|竞赛常用库函数|输入输出|String的使用|常见的数学方法|大小写转换

    🎥 个人主页:深鱼~ 🔥收录专栏:蓝桥杯 🌄欢迎 👍点赞✍评论⭐收藏 目录 一、编程基础 1.1 Java类的创建  1.2 Java方法  1.3 输入输出  1.4 String的使用 二、竞赛常用库函数 1.常见的数学方法 2.大小写转换 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,

    2024年01月21日
    浏览(70)
  • 【蓝桥杯备赛Java组】第一章·语言基础|竞赛常用库函数|输入输出|String的使用|常见的数学方法|大小写转换

    🎥 个人主页:深鱼~ 🔥收录专栏:蓝桥杯 🌄欢迎 👍点赞✍评论⭐收藏 目录 一、编程基础 1.1 Java类的创建  1.2 Java方法  1.3 输入输出  1.4 String的使用 二、竞赛常用库函数 1.常见的数学方法 2.大小写转换 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,

    2024年01月19日
    浏览(72)
  • Java 多线程之自定义线程池(ThreadPool)使用方法

    线程池是一种 管理和复用线程 的机制,它包含一组预先创建的线程,用于执行各种任务。线程池的主要作用是提高多线程应用程序的性能和效率,并提供对线程的生命周期和资源的管理,包括线程的创建、销毁和复用。 本文主要讨论线程池执行器(ThreadPoolExecutor)的用法,

    2024年04月26日
    浏览(39)
  • 使用代理IP池实现多线程爬虫的方法

    目录 前言 代理IP的概念和作用 为什么使用代理IP池 代理IP池的实现步骤 代码实现 注意事项 总结 随着互联网的发展,爬虫技术在各个领域中被广泛应用。然而,目标网站对爬虫的限制也日益严格,例如限制单个IP的请求频率。为了解决这个问题,使用代理IP池成为了一种常见

    2024年01月16日
    浏览(45)
  • netperf常用命令使用方法

    解决方案: 这个错误提示意味着netserver无法使用给定的IP地址和端口号来启动监听服务。可能的解决方案包括: 检查是否已经有其他程序在占用端口号12865。可以使用 netstat -tlnp 命令来列出当前正在监听的端口,并查找是否有其他程序正在使用12865端口。 使用sudo权限来启动

    2024年02月16日
    浏览(35)
  • Unity中常用函数使用方法

    Update() 正常更新,创建 JavaScript 脚本时默认添加这个方法,每一帧都会由系统调用一次该方法。 LateUpdate() 推迟更新,此方法在 Update() 方法执行完后调用,每一帧都调用一次。 FixedUpdate() 置于这个函数中的代码每隔一定时间执行一次。 Awake() 脚本唤醒,用于脚本的初始化,在

    2024年02月08日
    浏览(36)
  • 【Java中的Thread线程的简单方法介绍和使用详细分析】

    提示:若对Thread没有基本的了解,可以先阅读以下文章,同时部分的方法已经在如下两篇文章中介绍过了,本文不再重复介绍!! 【Java中Tread和Runnable创建新的线程的使用方法】 【Java中的Thread线程的七种属性的使用和分析】 提示:以下是本篇文章正文内容,下面案例可供参

    2024年02月15日
    浏览(39)
  • BigDecimal 基本使用和常用方法

    背景      涉及到比较大的数字之间的计算,使用float、double这样的浮点数就不那么准确了。因为不论是float 还是double都是浮点数,而计算机是二进制的,浮点数会失去一定的精确度。所以在 商业计算中基本 要用java.math.BigDecimal 结果输出:    1.2、BigDecimal还提供默认值创建

    2024年02月16日
    浏览(47)
  • 常用的Docker命令和使用方法

    目录 拉取(Pull)镜像 查看已下载的镜像 创建运行容器 列出正在运行的容器 停止和启动容器 进入容器 查看容器信息 查看容器日志 删除容器和镜像 重命名容器 帮助信息 拉取(Pull)镜像 当我们在Docker中部署一个应用程序时,需要使用一个称为\\\"镜像\\\"的模板来创建容器。镜

    2024年02月16日
    浏览(48)
  • 【Collection集合】概述、使用以及常用方法

    1.Collection集合的概述 它是单列集合的顶级接口,它表示一组对象,这些对象也称为Collection的元素 JDK不提供此接口的任何直接实现,它提供更具体地子接口(如set和list)实现 2.创建Collection集合的对象 多态的方式 具体的实现类ArrayList,在java.util包下需要导包 向集合里添加元

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包