首页 > 编程语言 >C++ 多线程知识汇总

C++ 多线程知识汇总

时间:2024-09-20 19:04:10浏览次数:8  
标签:std include lock 汇总 C++ 线程 dataQueue 多线程

https://zhuanlan.zhihu.com/p/194198073 (防链接失效)

程序使用并发的原因有两种:

  1. 为了关注点分离(程序中不同的功能,使用不同的线程去执行),当为了分离关注点而使用多线程时,设计线程的数量的依据,不再是依赖于 CPU 中的可用内核的数量,而是依据概念上的设计(依据功能的划分);
  2. 为了提高性能, 此时线程数量可以依据CPU的逻辑核心数目,这样可以使得每个线程能在不同的CPU核心上同时并发执行;

知道何时不使用并发与知道何时使用它一样重要。

不使用并发的唯一原因就是收益(性能的增幅)比不上成本(代码开发的脑力成本、时间成本,代码维护相关的额外成本)。运行越多的线程,操作系统需要为每个线程分配独立的栈空间,需要越多的上下文切换,这会消耗很多操作系统资源,如果在线程上的任务完成得很快,那么实际执行任务的时间要比启动线程的时间小很多,所以在某些时候,增加一个额外的线程实际上会降低,而非提高应用程序的整体性能,此时收益就比不上成本。而且多线程代码如果编写不当,运行中会出现很多问题,诸如执行结果不符合预期、程序崩溃等问题。

 

产生死锁的四个必要条件(面试考点):

  1. 互斥(资源同一时刻只能被一个进程使用)
  2. 请求并保持(进程在请资源时,不释放自己已经占有的资源)
  3. 不剥夺(进程已经获得的资源,在进程使用完前,不能强制剥夺)
  4. 循环等待(进程间形成环状的资源循环等待关系)

临界区速度最快,但只能作用于同一进程下不同线程,不能作用于不同进程;临界区可确保某一代码段同一时刻只被一个线程执行;

信号量多个线程同一时刻访问共享资源,进行线程的计数,确保同时访问资源的线程数目不超过上限,当访问数超过上限后,不发出信号量;

std::unique_lock 类似于 lock_guard,只是 std::unique_lock 用法更加丰富,同时支持 std::lock_guard() 的原有功能。 使用 std::lock_guard 后不能手动l ock() 与手动 unlock(),使用 std::unique_lock 后可以手动 lock() 与手动 unlock(); std::unique_lock 的第二个参数,除了可以是 adopt_lock,还可以是try_to_lock 与 defer_lock;

try_to_lock: 尝试去锁定,得保证锁处于 unlock 的状态,然后尝试现在能不能获得锁;尝试用 mutx 的 lock() 去锁定这个 mutex,但如果没有锁定成功,会立即返回,不会阻塞在那里,并继续往下执行;

defer_lock: 始化了一个没有加锁的 mutex;

std::condition_variable 是 C++ 中用于线程间同步的一个重要工具,可以让一个线程在某个条件不满足时等待,直到另一个线程通知它。

#include <iostream>
#include <thread>
#include <condition_variable>
#include <queue>
#include <atomic>

std::mutex mtx; // 互斥量
std::condition_variable cv; // 条件变量
std::queue<int> dataQueue; // 共享数据队列
std::atomic<bool> done(false); // 指示生产者是否完成

void producer() {
    for (int i = 0; i < 10; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟生产延迟
        {
            std::lock_guard<std::mutex> lock(mtx); // 锁定互斥量
            dataQueue.push(i); // 生产数据
            std::cout << "Produced: " << i << std::endl;
        }
        cv.notify_one(); // 通知一个等待的线程
    }
    done = true; // 标记生产结束
    cv.notify_all(); // 通知所有等待的线程
}

void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx); // 锁定互斥量
        cv.wait(lock, [] { return !dataQueue.empty() || done; }); // 等待条件变量
        
        if (dataQueue.empty() && done) {
            break; // 如果没有数据且生产已完成,退出循环
        }
        
        int data = dataQueue.front(); // 访问共享资源
        dataQueue.pop();
        std::cout << "Consumed: " << data << std::endl;
    }
}

int main() {
    std::thread prod(producer); // 启动生产者线程
    std::thread cons(consumer); // 启动消费者线程

    prod.join(); // 等待生产者线程结束
    cons.join(); // 等待消费者线程结束

    return 0;
}

 

标签:std,include,lock,汇总,C++,线程,dataQueue,多线程
From: https://www.cnblogs.com/strive-sun/p/18423081

相关文章

  • C++学习
    C++学习第三课缺省函数、函数重载与引用C++学习第一课:C++学习须知C++学习第二课:命名空间域C++学习第三课:缺省函数与函数重载文章目录C++学习第三课缺省函数、函数重载与引用前言一、C语言的第二个不足:缺省参数(默认参数)的使用1.当函数有两个及以上形参时的传参规......
  • C++ 多态
    一、多态的概念多态简单来说就是多种形态。多态又分为编译时多态(静态多态)和运行时多态(动态多态)。编译时多态(静态多态)主要就是我们一般讲的函数重载和函数模板。运行时多态,具体点就是去完成某个行为(函数),可以传不同的对象就会完成不同的行为,就达到多种形态。就像我们买火......
  • 亿级数据表多线程update锁表问题
    目录1、问题描述2、原因分析3、问题解决1、问题描述在pg数据库,某个业务,有一张数据表test,数据表结果如下:test(sjjbh,wlbid,gzmb,sfzg,zgsj,cjsj,xx...),这个表没有主键,会有很多重复数据。test表需要根据另外表(是多张表),动态更新sfzg字段, 加入另外表结构如下sjj_ckb1(......
  • 【Py/Java/C++三种语言OD独家2024E卷真题】20天拿下华为OD笔试之【模拟】2024E-转骰子
    可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录相关推荐阅读题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明解题思路构建长度为6的数组表......
  • C++顺序结构(2)
    一、变量、赋值语句与表达式1、天安门广场在北京市中心,它南北长880米,东西宽500米,试编一程序,计算天安门广场面积是多少平方米。点击查看代码1//试编程,计算天安门广场的面积是多少平方米2#include<iostream>//包含输入输出流头文件iostream3usingnamespacestd;......
  • 八个 C++ 开源项目,帮助初学者进阶成长
    通过参与或阅读开源项目的源代码,可以帮助你深入理解C++的各种概念和技术。ThreadPool一个简单的C++11线程池实现,只有一个头文件,代码加起来不到100行。GitHub地址:https://github.com/progschj/ThreadPoolsudokuC++实现的命令行数独游戏。600余行代码,初学者也可以轻松学习。......
  • c++高精度求平方根(保留整数)
    #include<iostream>#include<cstring>usingnamespacestd;constintSIZE=200;structhugeint{ intlen,num[SIZE];};hugeinttimes(hugeinta,hugeintb){ inti,j; hugeintans; memset(ans.num,0,sizeof(ans.num)); for(i=1;i<=......
  • 使用swig映射c++function
    swig可以自动生成从c++到其他语言如Java、Python等转换的中间语言,目前swig已经支持很多c++11的特性了,但是这次项目中发现function特性还没有支持,只能自己生成。从网上找了一份Java的java-HowtouseSWIGtowrapstd::functionobjects?-StackOverflow,我需要的c#的,故需要稍......
  • js数组合并与对象合并的方法汇总
    ......
  • C++ | 多态
     前言本篇博客讲解c++中的继承......