当前位置: 首页 > article >正文

C++ 并发专题 - C++线程同步的几种方法

一:概述

        线程同步是多线程编程中的一个重要概念,它用于控制多个线程之间对共享资源的访问,避免竞态条件(race condition)和数据不一致的问题。线程同步确保在多线程环境中,多个线程访问共享数据时能够按照某种预定的顺序或规则进行,以保证程序的正确性和稳定性。

二:线程同步方法

        1. 信号量


#include <iostream>
#include <semaphore>
#include <thread>
#include <vector>

std::vector<int> myVec{};

std::counting_semaphore<1> prepareSignal(0);

void prepareWork() {

    myVec.insert(myVec.end(), {0, 1, 0, 3});
    std::cout << "Sender: Data prepared."  << '\n';
    prepareSignal.release();
}

void completeWork() {

    std::cout << "Waiter: Waiting for data." << '\n';
    prepareSignal.acquire();
    myVec[2] = 2;
    std::cout << "Waiter: Complete the work." << '\n';
    for (auto i: myVec) std::cout << i << " ";
    std::cout << '\n';
    
}

int main() {

    std::cout << '\n';

    std::thread t1(prepareWork);
    std::thread t2(completeWork);

    t1.join();
    t2.join();

    std::cout << '\n';
  
}

        2. 条件变量



#include <iostream>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <vector>

std::mutex mut;
std::condition_variable condVar;

std::vector<int> myVec{};

void prepareWork() {                                       

    {
        std::lock_guard<std::mutex> lck(mut);
        myVec.insert(myVec.end(), {0, 1, 0, 3});           
    }
    std::cout << "Sender: Data prepared."  << '\n';
    condVar.notify_one();
}

void completeWork() {                                       

    std::cout << "Waiter: Waiting for data." << '\n';
    std::unique_lock<std::mutex> lck(mut);
    condVar.wait(lck, [] { return not myVec.empty(); });
    myVec[2] = 2;                                           
    std::cout << "Waiter: Complete the work." << '\n';
    for (auto i: myVec) std::cout << i << " ";
    std::cout << '\n';
    
}

int main() {

    std::cout << '\n';

    std::thread t1(prepareWork);
    std::thread t2(completeWork);

    t1.join();
    t2.join();

    std::cout << '\n';
  
}

        3. Atomic


#include <atomic>
#include <iostream>
#include <thread>
#include <vector>

std::vector<int> myVec{};

std::atomic<bool> atomicBool{false};

void prepareWork() {

    myVec.insert(myVec.end(), {0, 1, 0, 3});
    std::cout << "Sender: Data prepared."  << '\n';
    atomicBool.store(true);
    atomicBool.notify_one();

}

void completeWork() {

    std::cout << "Waiter: Waiting for data." << '\n';
    atomicBool.wait(false);                                
    myVec[2] = 2;
    std::cout << "Waiter: Complete the work." << '\n';
    for (auto i: myVec) std::cout << i << " ";
    std::cout << '\n';
    
}

int main() {

    std::cout << '\n';

    std::thread t1(prepareWork);
    std::thread t2(completeWork);

    t1.join();
    t2.join();

    std::cout << '\n';
  
}

        4. Promise - Feature 

#include <iostream>
#include <future>
#include <thread>
#include <vector>

std::vector<int> myVec{};

void prepareWork(std::promise<void> prom) {

    myVec.insert(myVec.end(), {0, 1, 0, 3});
    std::cout << "Sender: Data prepared."  << '\n';
    prom.set_value();                                    

}

void completeWork(std::future<void> fut){

    std::cout << "Waiter: Waiting for data." << '\n';
    fut.wait();                                           
    myVec[2] = 2;
    std::cout << "Waiter: Complete the work." << '\n';
    for (auto i: myVec) std::cout << i << " ";
    std::cout << '\n';
    
}

int main() {

    std::cout << '\n';

    std::promise<void> sendNotification;
    auto waitForNotification = sendNotification.get_future();

    std::thread t1(prepareWork, std::move(sendNotification));
    std::thread t2(completeWork, std::move(waitForNotification));

    t1.join();
    t2.join();

    std::cout << '\n';
  
}


http://www.kler.cn/a/441793.html

相关文章:

  • 数据结构-ArrayList和顺序表
  • 常用排序算法之插入排序
  • 使用插件SlideVerify实现滑块验证
  • HTML语言的数据库编程
  • 工业网口相机:如何通过调整网口参数设置,优化图像传输和网络性能,达到最大帧率
  • ingress-nginx代理tcp使其能外部访问mysql
  • Mysql 笔记2 emp dept HRs
  • DCDC降压模块
  • MyBatis 核心知识与实践
  • AndroidStudio——安卓项目结构与文件介绍
  • ubuntu+ros新手笔记(二):古月·ROS2入门21讲学习笔记
  • 【PostgreSQL异常解决】PostgreSQL 异常错误: PG::Error 服务意外关闭连接
  • 【ArcGIS技巧】天地图下载瓦片并合并成图片
  • Hive-4.0.1数据库搭建(可选配置用户名密码远程连接,涵盖切换为tez引擎)
  • FFmpeg 4.3 音视频-多路H265监控录放C++开发二十一.3,RTCP协议, RTCP协议概述,RTCP协议详情
  • 图数据库 | 15、可扩展的图数据库设计(上)
  • C# 读取EXCEL的数据批量插入单个PDF里的多个位置
  • 系统可观测性——Logback日志框架
  • Spring Boot 3.x:自动配置类加载机制的变化
  • 如何在Linux上搭建DHCP服务
  • 解决Docker拉取镜像报错问题的详细步骤
  • win10配置子系统Ubuntu子系统(无需通过Windows应用市场)实际操作记录
  • Python中构建全局字典的详细指南
  • docker快速实现ELK的安装和使用
  • Centos gcc 12.3 安装
  • 使用CNN模型训练图片识别(键盘,椅子,眼镜,水杯,鼠标)