并发编程之最小化共享

文章目录

      • **什么是「最小化共享」?**
      • **为什么要最小化共享?**
      • **如何实现最小化共享?**
        • **1. 线程局部存储(Thread-Local Storage)**
        • **2. 消息传递(Message Passing)**
        • **3. 不可变数据(Immutable Data)**
        • **4. 副本传递(Copy-On-Write)**
      • **典型应用场景对比**
      • **设计原则总结**

什么是「最小化共享」?

最小化共享(Minimize Sharing)是并发编程中的核心原则,指在多线程设计中尽量减少线程间共享数据的数量,从而降低数据竞争风险、提升性能、简化代码逻辑。其本质是通过设计模式减少或消除对共享资源的直接访问。


为什么要最小化共享?

  1. 降低锁竞争:减少共享数据意味着减少需要加锁的区域,提升并发性能。
  2. 避免数据竞争:共享数据越少,线程间意外干扰的可能性越低。
  3. 简化代码:无需处理复杂的同步逻辑,代码更易维护。

如何实现最小化共享?

以下是常见的实现模式及示例:

1. 线程局部存储(Thread-Local Storage)
  • 原理:每个线程拥有独立的数据副本,互不干扰。

  • 适用场景:线程需要独立计算,无需共享中间结果。

    #include <thread>
    #include <iostream>thread_local int local_counter = 0; // 每个线程独立副本void worker() {for(int i = 0; i < 1000; ++i) {local_counter++; // 无锁安全操作}std::cout << "Thread " << std::this_thread::get_id() << " counter: " << local_counter << "\n";
    }int main() {std::thread t1(worker);std::thread t2(worker);t1.join(); t2.join();return 0;
    }
    
2. 消息传递(Message Passing)
  • 原理:线程通过消息队列通信,而非直接共享内存。

  • 适用场景:生产者-消费者模型、任务分发。

    #include <queue>
    #include <thread>
    #include <mutex>
    #include <condition_variable>template<typename T>
    class MessageQueue {
    public:void push(const T& msg) {std::lock_guard<std::mutex> lock(mtx_);queue_.push(msg);cond_.notify_one();}T pop() {std::unique_lock<std::mutex> lock(mtx_);cond_.wait(lock, [this]{ return !queue_.empty(); });T msg = queue_.front();queue_.pop();return msg;}private:std::queue<T> queue_;std::mutex mtx_;std::condition_variable cond_;
    };// 使用示例
    MessageQueue<int> msg_queue;void producer() {for(int i = 0; i < 10; ++i) {msg_queue.push(i); // 发送消息}
    }void consumer() {while(true) {int num = msg_queue.pop(); // 接收消息std::cout << "Received: " << num << "\n";}
    }
    
3. 不可变数据(Immutable Data)
  • 原理:共享数据一旦创建便不可修改,无需同步。

  • 适用场景:配置信息、历史记录等只读数据。

    struct Config {const int max_connections; // 常量const std::string log_path; Config(int mc, std::string lp): max_connections(mc), log_path(std::move(lp)) {}
    };// 全局只读配置
    const auto global_config = std::make_shared<const Config>(100, "/var/log");
    
4. 副本传递(Copy-On-Write)
  • 原理:需要修改数据时创建副本,保持原始数据不变。

  • 适用场景:读多写少的数据结构。

    #include <vector>
    #include <mutex>class SafeVector {
    public:// 读操作:无锁访问副本std::vector<int> get_data() const {std::lock_guard<std::mutex> lock(mtx_);return data_; // 返回副本}// 写操作:修改副本后替换void add(int value) {std::lock_guard<std::mutex> lock(mtx_);auto new_data = data_; // 创建副本new_data.push_back(value);data_.swap(new_data); // 原子替换}private:std::vector<int> data_;mutable std::mutex mtx_;
    };
    

典型应用场景对比

场景传统共享方式最小化共享方案优势
计数器统计多个线程累加共享变量(需加锁)线程局部存储 + 最终合并无锁操作,性能高
实时数据处理直接操作共享数据队列(需同步)消息队列传递数据副本解耦生产消费逻辑
全局配置读取多线程读取可能被修改的共享配置只读不可变数据无需同步,绝对安全
用户会话管理共享用户状态表(需复杂锁机制)每个连接独立处理 + 无状态设计避免锁竞争,扩展性强

设计原则总结

  1. 能不共享就不共享:优先使用线程独立数据。
  2. 必须共享则只读:通过不可变数据减少同步需求。
  3. 读写分离:写操作通过副本或消息队列隔离。
  4. 异步化处理:用消息传递代替直接共享内存。

通过最小化共享,可以构建更高效、更健壮的并发系统,减少多线程编程中的常见陷阱。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通信之光纤耦合器

以下是关于光纤耦合器的详细介绍&#xff1a; 定义与原理 - 定义&#xff1a;光纤耦合器是一种能使传输中的光信号在特殊结构的耦合区发生耦合&#xff0c;并进行再分配的器件&#xff0c;也叫分歧器、连接器、适配器、光纤法兰盘。 - 原理&#xff1a;利用不同光纤面紧邻光纤芯…

自然语言模型的演变与未来趋势:从规则到多模态智能的跨越

自然语言模型的演变与未来趋势&#xff1a;从规则到多模态智能的跨越 自然语言处理(NLP)作为人工智能领域最具挑战性的分支之一&#xff0c;在过去几十年经历了翻天覆地的变化。从最初基于规则的系统到如今拥有万亿参数的大型语言模型(LLMs)&#xff0c;这一技术革新不仅彻底改…

笔记本电脑更换主板后出现2203:System configuration is invalid,以及2201、2202系统错误的解决

笔记本电脑更换主板后启动出现2203:System configuration is invalid,以及2201、2202系统错误的解决 自用的一台ThinkpadT490笔记本电脑 ,由于主板故障,不得不更换主板,通过某宝购置主板后进行了更换。 具体拆卸笔记本可搜索网络视频教程。 注意: 在更换主板时,注意先拍…

JavaScript中的观察者模式

以下是关于 观察者模式(Observer Pattern) 的全面梳理,涵盖核心概念、实现方式、应用场景及注意事项,帮助我们掌握这一解耦事件通知与处理的经典设计模式: 一、观察者模式基础 1. 核心概念 定义:定义对象间 一对多 的依赖关系,当被观察对象(Subject)状态变化时,自动…

RAG基建之PDF解析的“流水线”魔法之旅

将PDF文件和扫描图像等非结构化文档转换为结构化或半结构化格式是人工智能的关键部分。然而,由于PDF的复杂性和PDF解析任务的复杂性,这一过程显得神秘莫测。 在RAG(Retrieval-Augmented Generation)基建之PDF解析的“魔法”与“陷阱”中,我们介绍了PDF解析的主要任务,对现…

【Linux】GDB调试指南

一、GDB基础 1. 启动调试 gdb ./your_program # 启动调试 gdb --args ./prog arg1 # 带参数启动 gdb -p <pid> # 附加到正在运行的进程 2. 断点管理 b main # 在main函数设断点 b file.c:20 # 在file.c第20行设断点 b *0x4005a…

Android面试总结之Glide源码级理解

当你的图片列表在低端机上白屏3秒、高端机因内存浪费导致FPS腰斩时&#xff0c;根源往往藏在Glide的内存分配僵化、磁盘混存、网络加载无优先级三大致命缺陷中。 本文从阿里P8级缓存改造方案出发&#xff0c;结合Glide源码实现动态内存扩容、磁盘冷热分区、智能预加载等黑科技&…

驱动开发系列49 - 搭建 Vulkan 驱动调试环境(编译 mesa 3D)- Ubuntu24.04

一:搭建Vulkan运行环境 安装vulkan依赖包: 1. sudo apt install vulkan-tools 2. sudo apt install libvulkan-dev 3. sudo apt install vulkan-utility-libraries-dev spirv-tools 4. sudo apt install libglfw3-dev libglm-dev 5. sudo apt install libxxf86vm-dev libxi-…

深度学习——图像余弦相似度

计算机视觉是研究图像的学问&#xff0c;在图像的最终评价时&#xff0c;往往需要用到一些图像相似度的度量指标&#xff0c;因此&#xff0c;在本文中我们将详细地介绍原生和调用第三方库的计算图像余弦相似度的方法。 使用原生numpy实现 import numpy as npdef image_cosin…

项目代码第8讲【数据库基础知识】:SQL(DDL、DML、DQL、DCL);函数(聚合、字符串、数值、日期、流程);约束;多表查询;事务

黑马程序员 MySQL数据库入门到精通&#xff0c;从mysql安装到mysql高级、mysql优化全囊括_哔哩哔哩_bilibili 一、数据库相关概念 1、主流的关系型数据库都支持SQL语言——SQL语言可以操作所有的关系型数据库 像MySQL、Oracle Database、Microsoft SQL Server、IBM Db2等主流的…

如何在阿里云linux主机上部署Node.Js

在阿里云的Linux服务器上搭建Node.js编程环境可以通过以下步骤完成。这里以常见的 Ubuntu/CentOS 系统为例&#xff0c;提供两种安装方式&#xff08;包管理器、NVM多版本管理&#xff09;&#xff1a; 一、通过包管理器安装&#xff08;适合快速安装指定版本&#xff09; 1. …

Python爬虫:开启数据抓取的奇幻之旅(一)

目录 一、爬虫初印象&#xff1a;揭开神秘面纱​ 二、工欲善其事&#xff1a;前期准备​ &#xff08;一&#xff09;Python 环境搭建​ 1.下载 Python 安装包&#xff1a;​ 2.运行安装程序&#xff1a;​ 3.配置环境变量&#xff08;若自动添加失败&#xff09;&#x…

机器学习——集成学习框架(GBDT、XGBoost、LightGBM、CatBoost)、调参方法

一、集成学习框架 对训练样本较少的结构化数据领域&#xff0c;Boosting算法仍然是常用项 XGBoost、CatBoost和LightGBM都是以决策树为基础的集成学习框架 三个学习框架的发展是&#xff1a;XGBoost是在GBDT的基础上优化而来&#xff0c;CatBoost和LightGBM是在XGBoost的基础上…

第十五章:Python的Pandas库详解及常见用法

在数据分析领域&#xff0c;Python的Pandas库是一个不可或缺的工具。它提供了高效的数据结构和数据分析工具&#xff0c;使得数据处理变得简单而直观。本文将详细介绍Pandas库的基本功能、常见用法&#xff0c;并通过示例代码演示如何使用Pandas进行数据处理。最后&#xff0c;…

【Python桌面应用】PySide6 界面开发完全指南

文章目录 1. 引言2. PySide6 简介与安装2.1 什么是PySide62.2 PySide6 vs. PyQt62.3 安装PySide62.4 开发环境配置建议 3. Qt 设计原理3.1 Qt对象模型3.2 信号与槽机制3.3 Qt坐标系统3.4 Qt样式表(QSS) 4. 创建第一个应用4.1 基本应用结构4.2 主窗口与应用生命周期4.3 使用面向…

用 pytorch 从零开始创建大语言模型(三):编码注意力机制

从零开始创建大语言模型&#xff08;Python/pytorch &#xff09;&#xff08;三&#xff09;&#xff1a;编码注意力机制 3 编码注意力机制3.1 建模长序列的问题3.2 使用注意力机制捕捉数据依赖关系3.3 通过自注意力关注输入的不同部分3.3.1 一个没有可训练权重的简化自注意力…

Spring中的IOC及AOP概述

前言 Spring 框架的两大核心设计思想是 IOC&#xff08;控制反转&#xff09; 和 AOP&#xff08;面向切面编程&#xff09;。它们共同解决了代码耦合度高、重复逻辑冗余等问题。 IOC&#xff08;控制反转&#xff09; 1.核心概念 控制反转&#xff08;Inversion of Control…

STM32_HAL开发环境搭建【Keil(MDK-ARM)、STM32F1xx_DFP、 ST-Link、STM32CubeMX】

安装Keil(MDK-ARM)【集成开发环境IDE】 我们会在Keil(MDK-ARM)上去编写代码、编译代码、烧写代码、调试代码。 Keil(MDK-ARM)的安装方法&#xff1a; 教学视频的第02分03秒开始看。 安装过程中请修改一下下面两个路径&#xff0c;避免占用C盘空间。 Core就是Keil(MDK-ARM)的…

python 第三方库 - dotenv读取配置文件

.env 文件是一种用于存储环境变量的配置文件&#xff0c;常用于项目的运行环境设置。环境变量是操作系统层面的一些变量&#xff0c;它们可以被应用程序访问和使用&#xff0c;通常包含敏感信息或特定于环境的配置&#xff0c;如数据库连接信息、API 密钥、调试模式等。 安装p…