C++多线程运行整理

一.多线程运行

复制代码
#include <iostream>
#include <thread>

void print_id(int id)
{
    std::cout << "ID:" << id <<  ",线程ID为:" << std::this_thread::get_id() <<std::endl;
}
int main(void)
{   
    std::thread t1(print_id,1);
    t1.join();
    std::thread t2(print_id,2);
    t2.join();
    return 0;
}

二.多线程并发的实现方式

1.使用函数指针

复制代码
// 多线程并发1_使用函数指针
// 使用多线程的库,来实现并行计算的加法

#include <iostream>   
#include <thread>

int sum = 0;
float avg = 0;
void add(int a,int b)
{
    sum += a + b;
}

void Avg(int a,int b)
{
    avg = (a + b)/2;
}

int main()
{
    int a = 5;
    int b = 10;
    std::thread t1(add,a,b);
    t1.join();
    std::cout << "线程1和为:" << sum <<std::endl;
    
    std::thread t2(add,a,b);
    t2.join();
    std::cout << "线程2和为:" << sum <<std::endl;
    
    std::thread t3(Avg,a,b);
    t3.join();
    std::cout << "线程3平均为:" << avg <<std::endl;
    return 0;
}

|---------------------|-----------------|---------------------------------|
| 全局变量无锁保护 | 多线程共享变量,有数据竞争风险 | 使用 std::mutex |
| std::thread 无法返回值 | 不能直接获取线程函数的返回值 | 改用 std::async + std::future |

2.使用函数对象

复制代码
// 多线程并发2_使用函数对象
// 通过类中的 operator() 方法定义函数对象来创建线程

#include <iostream>   
#include <thread>

class PrintTask
{
public:
    void operator()(int count) const{
        for (int i = 0;i < count;++i){
            std::cout << "第" << i+1 << "次使用函数对象(function object)创建多线程!\n";
        }
    }
};

int main (){
    std::thread t2(PrintTask(),5);//创建线程,传递函数对象和参数
    t2.join(); //等待线程完成
    return 0;
}

3.使用Lambda表达式

复制代码
// 多线程并发3_使用Lambda表达式
// 使用Lambda表达式可以直接内联定义线程执行的代码

#include <iostream>   
#include <thread>
int main(){
    std::thread t3([](int count){
        for (int i = 0;i < count; ++i){
            std::cout << "第" << i+1 << "次使用Lambda表达式执行线程!\n" ;
        }
    },5);//创建线程,传递Lambda表达式和参数
    t3.join();//等待线程完成
    return 0;
}

三.整合3种多线程并发创建方式融合展示

复制代码
/*
将函数指针,函数对象和Lambda表达式 3种方式创建线程进行融合展示
*/

#include <iostream>
#include <thread>
using namespace std;

//一个简单的函数,作为线程的入口函数
void foo(int Z){
    for (int i = 0;i < Z;i++){
        cout << "线程使用函数指针作为可调用参数\n";
    }
}

//可调用对象的类定义
class ThreadObj{
    public:
        void operator()(int x) const{
            for (int i = 0;i < x;i++){
                cout << "线程使用函数对象作为可调用参数\n";
            }
        }
};

int main(){
    cout << "线程1,2,3独立运行" << endl;
    //使用函数指针创建线程
    thread th1(foo,3);

    //使用函数对象创建线程
    thread th2(ThreadObj(),3);

    //使用Lambda表达式创建线程
    thread th3([] (int x){
        for (int i = 0;i < x;i++){
            cout << "线程使用Lambda表达式作为可调用参数\n";
        }
    },3);

    //等待所有线程完成
    th1.join(); //等待线程th1完成
    th2.join(); //等待线程th2完成
    th3.join(); //等待线程th3完成
    return 0;
}

整理不易,诚望各位看官点赞 收藏 评论 予以支持,这将成为我持续更新的动力源泉。若您在阅览时存有异议或建议,敬请留言指正批评,让我们携手共同学习,共同进取,吾辈自当相互勉励!

相关推荐
合作小小程序员小小店4 小时前
web网页开发,旧版在线%考试,判题%系统demo,基于python+flask+随机分配考试题目,基于开发语言python,数据库mysql
开发语言·后端·python·mysql·flask·html5
蜗牛沐雨4 小时前
C++ 输出流(Output Stream)全解析
开发语言·c++
余道各努力,千里自同风4 小时前
如何使用 Promise.all() 处理异步并发操作?
开发语言·前端·javascript
小白讲编程5 小时前
C++ 基础学习总结:从入门到构建核心认知
c++·学习·青少年编程
国服第二切图仔5 小时前
Rust开发之使用 Trait 定义通用行为——实现形状面积计算系统
开发语言·网络·rust
AI科技星5 小时前
基于空间螺旋运动假设的水星近日点进动理论推导与验证
数据结构·人工智能·经验分享·算法·计算机视觉
前端小咸鱼一条5 小时前
14. setState是异步更新
开发语言·前端·javascript
L_09075 小时前
【Algorithm】Day-10
c++·算法·leetcode
大大dxy大大5 小时前
sklearn-提取字典特征
人工智能·算法·sklearn