理解CAS与__sync_bool_compare_and_swap

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

      CAS是compare and swap,   简单来说就是,在写入新值之前, 读出旧值, 当且仅当旧值与存储中的当前值一致时,才把新值写入存储。__sync_bool_compare_and_swap是可供程序员调用的接口, 为什么需要CAS呢? 一起来看下:

       让10个线程执行加法操作, 看看最简单的版本:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

int sum = 0;

void* adder(void *p)
{
    for(int i = 0; i < 1000000; i++)  // 百万次
    {
        sum++;
    }

    return NULL;
}

int main()
{
    pthread_t threads[10];

    for(int i = 0; i < 10; i++)
    {
        pthread_create(&threads[i], NULL, adder, NULL);
    }
	
    for(int i = 0; i < 10; i++)
    {
        pthread_join(threads[i],NULL);
    }

	printf("sum is %d\n", sum);
}

          运行了一下, 发现每次结果不一样, 并不是10000000, 原因很简单, 多线程没有同步。 结果也说明,++不是原子操作。

  

          怎么办? 加锁, 这是无疑的, 如下:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

int sum = 0;
pthread_mutex_t mutex;

void* adder(void *p)
{
    for(int i = 0; i < 1000000; i++)  // 百万次
    {
    	pthread_mutex_lock(&mutex);
        sum++;
		pthread_mutex_unlock(&mutex);
    }

    return NULL;
}

int main()
{
    pthread_t threads[10];
    pthread_mutex_init(&mutex, NULL);

    for(int i = 0; i < 10; i++)
    {
        pthread_create(&threads[i], NULL, adder, NULL);
    }
	
    for(int i = 0; i < 10; i++)
    {
        pthread_join(threads[i],NULL);
    }

	printf("sum is %d\n", sum);
}

        多次运行发现, 结果总是10000000, 加锁了, 安全。 

        但是, 问题来了, 加锁效率如何, 多进程,多机器修改怎么办?  比如典型的银行卡扣款场景。 且看CAS机制:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

int sum = 0;

void* adder(void *p)
{
    int old = sum;
    for(int i = 0; i < 1000000; i++)  // 百万次
    {
        while(!__sync_bool_compare_and_swap(&sum, old, old + 1))  // 如果old等于sum, 就把old+1写入sum
        {
           old = sum; // 更新old
        }
    }

    return NULL;
}

int main()
{
    pthread_t threads[10];
    for(int i = 0;i < 10; i++)
    {
        pthread_create(&threads[i], NULL, adder, NULL);
    }
	
    for(int i = 0; i < 10; i++)
    {
        pthread_join(threads[i], NULL);
    }

    printf("sum is %d\n",sum);
}

          结果是10000000, 可以好好理解下。 有兴趣的同学, 可以测测上述程序的效率。

          对了, 最后一个程序的编译方法为:g++ test.cpp  -lpthread -march=nocona -mtune=generic

 

         不多说。

 

 

我常用的 C++ 读写锁 锁操作是为了线程安全,下面写一个我常用的 C++ 自旋锁,简单高效。#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <sys/time.h> #include <errno.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h>templat 阅读详情

相关推荐

c++ 高并发队列的实现

JAVA如何进行CAS 讲到java的队列时,讲到java中的CAS操作 回顾下java中的cas,主要采用compareAndSet方法,如AtomicReference中所使用的: AtomicRefrence.java /** * Atomically sets the value to the given updated value * if the current value {@code ==} the expected value. * @param expect

BBinChina的专栏 2397

loom:C99 的无锁线程池

loom -- C99 的无锁线程池 Loom 创建一个任务队列和工作线程池。 工作人员按计划运行任务,否则睡眠直到工作可用。 注意:这仍处于开发初期。 我已经在多核 x86 / x86-64 系统上对其进行了压力测试,它应该是安全无锁的,但在具有不同内存屏障的硬件平台上可能存在竞争条件。 __sync_bool_compare_and_swap在内部使用,因此可移植性将仅限于该功能可用的平台/编译器。 构建状态 主要特征: 无锁:通过在内部使用操作来避免锁争用开销。 无分配:初始化后不分配。 背压支持:backlog 大小是公开的,以允许对填充队列的上游代码进行成比例的推回。 可以针对特定应用程序调整线程数和任务队列的大小。 ISC 许可证:您可以自由使用它,甚至可以用于商业目的。 入门 首先,初始化线程池: /* The default configuration. I

c++11 atomic 内存序

5.test_and_set() 函数检查 std::atomic_flag 标志,如果 std::atomic_flag 之前没有被设置过,则设置 std::atomic_flag 的标志,并返回先前该 std::atomic_flag 对象是否被设置过,如果之前 std::atomic_flag 对象已被设置,则返回 true,否则返回 false。3. 初始状态c++20之前不确定 ,c++20之后是false。7. c++20以前只提供了上面两个方法。

qixiang2013的专栏 951

__sync_bool_compare_and_swap原子函数

__sync_bool_compare_and_swap(&value, old, new); 在写入新值之前, 读出旧值, 当且仅当旧值存储中的当前值一致时,才把新值写入存储; 返回值:写入新值成功返回1,写入失败返回0(即旧值存储中当前的值一致时写入成功,返回1) bjb@bjb-VirtualBox:~/test$ cat cas.c #include <stdio.h> #include <pthread.h> #include <unistd.h&.

qq_29044159的博客 1万+

使用`__sync_bool_compare_and_swap`实现原子操作

使用`__sync_bool_compare_and_swap`实现原子操作

深耕嵌入式领用多年, 致力于分享嵌入式领域技术! 1806

理解CAS__sync_bool_compare_and_swap(原子操作)

CAScompare and swap, 简单来说就是,在写入新值之前, 读出旧值, 当且仅当旧值存储中的当前值一致时,才把新值写入存储。__sync_bool_compare_and_swap是可供程序员调用的接口, 为什么需要CAS呢? 一起来看下: 让10个线程执行加法操作, 看看最简单的版本: #include <stdio.h> #include <pthread.h> #include <unistd.h> int sum =...

weixin_39094034的博客 3327

__sync_bool_compare_and_swap

【代码】__sync_bool_compare_and_swap

jason的专栏 424

nginx源码学习记录(一)

今天正式开始通过阅读nginx源码来进行服务器开发学习。 首先从 nginx.c 的main入口开始。 一开始 ngx_strerror_init() 错误初始化函数就让我学习到了一个小技巧,在初始化阶段把linux下所有的strerror放入error数组,使得在程序运行时,不需要再调用strerror来获取错误信息。 随后,在搜索__sync_bool_compare_and

sharp_spear的专栏 333

ngx_trylock

结果输出到当前目录的打开这个文件查找函数由此可以确认。

weixin_41812346的博客 211

从CPU硬件指令到Go语言sync.Mutex:一条你看得懂的并发锁进化史

本文深入探讨了从CPU硬件指令到Go语言sync.Mutex的并发锁进化历程。通过分析test_and_set等硬件同步指令、操作系统内核的封装机制,以及Go语言sync.Mutex的设计优化,揭示了现代同步原语的技术谱系。文章还提供了锁使用的黄金法则和性能优化技巧,帮助开发者更好地理解和应用并发编程中的互斥机制。

weixin_30466039的博客 403

互斥锁、自旋锁以及原子操作的简单了解及使用(C语言)

互斥锁、自旋锁以及原子操作的简单了解及使用(C语言)

m0_62287395的博客 560

C++:Lock-free;atomic;CAS;cmpxchg

libstdc+±v3/libsupc++/atomic_lockfree_defines.h /** * Lock-free property. * * 0 indicates that the types are never lock-free. * 1 indicates that the types are sometimes lock-free. * 2 indicates that the types are always lock-free. */ #if __cplusplus

mzhan017的博客 1485

CAS原子操作实现无锁及性能分析

  CAS原子操作实现无锁及性能分析   Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn.net/chen19870707 Date:Nov 13th, 2014 近期在研究nginx的自旋锁的时候,又见到了GCC CAS原子操作,于是决定动手分析下CAS实现的无锁究竟性能...

weixin_34309435的博客 96

500行C++实现高性能无锁队列:原理、实战性能优化

在多线程编程中,线程同步是保证数据安全的核心机制,传统方法如互斥锁(Mutex)通过阻塞线程实现,但会引入性能开销和死锁风险。其原理是控制临界区访问,技术价值在于简化并发模型。随着对高并发和低延迟系统的需求增长,无锁编程(Lock-Free Programming)应运而生,它利用原子操作和内存屏障,允许多线程非阻塞地协作,从而在高争用场景下显著提升吞吐量并降低延迟。这种技术尤其适用于后台服务、游戏服务器和高频交易等对性能有极致要求的应用场景。本文以C++原子操作和内存模型为基础,深入解析无锁队列的设计

weixin_34259232的博客 429

Yac:基于共享内存的无锁缓存架构深度解析技术实现原理

Yac(Yet Another Cache)是专为PHP设计的高性能、无锁共享内存用户数据缓存系统,旨在解决传统缓存方案在高并发场景下的性能瓶颈问题。通过创新的内存架构设计和原子操作实现,Yac在单机多进程环境下提供了接近内存访问速度的缓存服务,成为替代APC和本地memcached的优选方案。 ## 无锁缓存架构的核心设计理念 ### 传统缓存方案的性能瓶颈分析 在高并发PHP应用中,传统

gitblog_00695的博客 832
上一篇: 我的历届世界杯记忆
下一篇: 巧用CAS解决数据一致性问题
涛歌依旧
涛歌依旧 优质创作者: 后端开发技术领域 优质创作者: 后端开发技术领域 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄14年 28万+粉丝 2592原创
评论 14
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值