0

0

C++并发实战19:lock free编程

雪夜

雪夜

发布时间:2025-07-20 08:42:02

|

796人浏览过

|

来源于php中文网

原创

大家好,又见面了,我是你们的朋友全栈君。涉及到并行/并发计算时,通常都会想到使用锁来保护共享的数据,但锁的使用也存在一些问题:

  1. 效率降低:由于临界区无法并发运行,进入临界区需要等待,锁的使用导致效率下降。多核CPU也无法充分发挥其性能。
  2. 死锁风险:在复杂的情况下,很容易造成死锁,导致并发进程或线程之间无止境地互相等待。
  3. 中断/信号处理函数中的限制:在中断或信号处理函数中不能使用锁,这给并发处理带来了困难。
  4. 影响实时性:锁会影响实时性,等待时间不确定。
  5. 优先级反转:高优先级的线程可能需要等待低优先级的线程。
  6. 线程挂起问题:如果一个线程在持有锁的情况下挂起,会影响其他等待该锁的线程。

总之,在基于锁的多线程/多进程编程中,你需要确保对竞争条件敏感的共享数据上的任何操作,都通过加锁或解锁一个互斥锁(mutex)来实现原子操作。

现有的加锁和无锁编程的种类如下:

C++并发实战19:lock free编程

其中,标注为红色字体的方案为Blocking synchronization(需要锁),黑色字体的为Non-blocking synchronization(无锁)。Lock-based和Lockless-based两者之间的区别仅仅是加锁粒度的不同。图中最底层的方案就是大家经常使用的mutex和semaphore等方案,代码复杂度低,但运行效率也最低。

立即学习C++免费学习笔记(深入)”;

AI小聚
AI小聚

一站式多功能AIGC创作平台,支持AI绘画、AI视频、AI聊天、AI音乐

下载

可以使用std::atomic来实现lock free编程,但这里并不是真正的无锁,只有atomic_flag是无锁的,其他atomic内部都是有锁的,只不过粒度很小。atomic::compare_exchange_weak/strong等同于CAS(比较并交换)操作,在C++11之前该操作是平台相关的,现在atomic将其实现为成员函数。

下面是一个lock free的栈的示例:

#include <atomic>
#include <memory>
<p>template<typename T>
class lock_free_stack // 栈的底层数据结构采用单向链表实现
{
private:
struct node
{
std::shared_ptr<T> data; // 这里采用shared<em>ptr管理的好处在于:若栈内存放对象,pop中return栈顶对象可能拷贝异常,栈内只存储指针还可以提高性能
node* next;
node(T const& data</em>) : data(std::make<em>shared<T>(data</em>)) // 注意make_shared比直接shared_ptr构造的内存开销小
{}
};
std::atomic<node*> head; // 采用原子类型管理栈顶元素,主要利用atomic::compare_exchange_weak实现lock free</p><p>public:
void push(T const& data)
{
node* const new_node = new node(data);
new_node->next = head.load(); // 每次从链表头插入
while (!head.compare_exchange_weak(new_node->next, new_node)); // 若head==new_node->next则更新head为new_node,返回true结束循环,插入成功;若head!=new_node->next表明有其它线程在此期间对head操作了,将new_node->next更新为新的head,返回false,继续进入下一次while循环。这里采用atomic::compare_exchange_weak比atomic::compare_exchange_strong快,因为compare_exchange_weak可能在元素相等的时候返回false所以适合在循环中,而atomic::compare_exchange_strong保证了比较的正确性,不适合用于循环
}</p><pre class="brush:php;toolbar:false;"><code>std::shared_ptr<T> pop()
{
    node* old_head = head.load(); // 拿住栈顶元素,但是可能后续被更新,更新发生在head!=old_head时
    while (old_head && !head.compare_exchange_weak(old_head, old_head->next)); // 这里注意首先要先判断old_head是否为nullptr防止操作空链表,然后按照compare_exchange_weak语义更新链表头结点。若head==old_head则更新head为old_head->next并返回true,结束循环,删除栈顶元素成功;若head!=old_head表明在此期间有其它线程操作了head,因此更新old_head为新的head,返回false进入下一轮循环,直至删除成功。
    return old_head ? old_head->data : std::shared_ptr<T>(); // 这里注意空链表时返回的是一个空的shared_ptr对象
} // 这里只是lock free,由于while循环可能无限期循环不能在有限步骤内完成,故不是wait free

};

发布者:全栈程序员栈长,转载请注明出处:https://www.php.cn/link/46c6a6c72edf42b1335217a9eb4b2325 原文链接:https://www.php.cn/link/c8377ad2a50fb65de28b11cfc628d75c

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

443

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

605

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

377

2025.12.24

java多线程相关教程合集
java多线程相关教程合集

本专题整合了java多线程相关教程,阅读专题下面的文章了解更多详细内容。

32

2026.01.21

C++多线程相关合集
C++多线程相关合集

本专题整合了C++多线程相关教程,阅读专题下面的的文章了解更多详细内容。

29

2026.01.21

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

103

2026.02.06

http与https有哪些区别
http与https有哪些区别

http与https的区别:1、协议安全性;2、连接方式;3、证书管理;4、连接状态;5、端口号;6、资源消耗;7、兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2910

2024.08.16

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 7.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号