CAS原子锁 高效自旋无锁的正确用法
"atomic_lock.h"
#pragma once #ifndef _atomic_lock_h_include_ #define _atomic_lock_h_include_ #define spin_num (2048) #ifdef _MSC_VER #include <windows.h> #define cpu_pause() __asm {pause} #define thread_yield() Yield() __forceinline int compare_and_swap(long volatile *des, long out, long set) { InterlockedCompareExchange(des, set, out); return *des == set; } #endif #ifdef __GNUC__ #include <sched.h> #define cpu_pause() __asm__ ("pause") #define thread_yield() sched_yield() #if defined(__INTEL_COMPILER) || (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1)) #define USE_BUILTINS #endif static inline int compare_and_swap(volatile long* x, long oldval, long newval) { #ifdef USE_BUILTINS return __sync_bool_compare_and_swap(x, oldval, newval); #elif defined(__i386__) char result; asm volatile ("lock; cmpxchgl %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory"); return result; #elif defined(__x86_64__) char result; asm volatile ("lock; cmpxchgq %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory"); return result; #else #error architecture not supported and gcc too old. #endif } #endif typedef struct { volatile long lock; } app_atomic_lock_t; int app_atomic_trylock(app_atomic_lock_t* lt, long value); void app_atomic_lock(app_atomic_lock_t* lt, long value); void app_atomic_unlock(app_atomic_lock_t* lt, long value); #endif
"atomic_lock.c"
#include "atomic_lock.h" int app_atomic_trylock(app_atomic_lock_t * lt, long value) { && compare_and_swap(<-> } void app_atomic_lock(app_atomic_lock_t * lt, long value) { u_int n, i; for (;; ) { && compare_and_swap(<->, value)) { return; } ; n < spin_num; n <<= ) { ; i < n; i++) { cpu_pause(); } && compare_and_swap(<->, value)) { return; } } thread_yield(); } } void app_atomic_unlock(app_atomic_lock_t * lt, long value) { compare_and_swap(<->); }
#include "atomic_lock.h" app_atomic_lock_t lock; volatile int value; void* th_fun(void *arg) { int i; ; i < ; i++){ app_atomic_lock(&); value++; app_atomic_unlock(&); } return NULL; } int main() { ; pthread_t th1, th2; pthread_create(&th1, NULL, th_fun, NULL); pthread_create(&th2, NULL, th_fun, NULL); pthread_join(th1, NULL); pthread_join(th2, NULL); printf("%d\n", value); ; }
cas在loop抢占的时候,会大量消耗cpu,在x86指令集下,可以用pause指令来减少loop的消耗。
cas锁在极高并发时候,会有非常大的帮助,相反,抢占时间过长,则千万不要用cas无锁。
CAS原子锁 高效自旋无锁的正确用法的更多相关文章
- JDK1.8 LongAdder 空间换时间: 比AtomicLong还高效的无锁实现
我们知道,AtomicLong的实现方式是内部有个value 变量,当多线程并发自增,自减时,均通过CAS 指令从机器指令级别操作保证并发的原子性. // setup to use Unsafe.co ...
- CAS(Compare and Swap)无锁算法-学习笔记
非阻塞同步算法与CAS(Compare and Swap)无锁算法 这篇问题对java的CAS讲的非常透彻! 锁的代价 1. 内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的 ...
- 非阻塞同步算法与CAS(Compare and Swap)无锁算法
锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...
- 【Java并发编程】9、非阻塞同步算法与CAS(Compare and Swap)无锁算法
转自:http://www.cnblogs.com/Mainz/p/3546347.html?utm_source=tuicool&utm_medium=referral 锁(lock)的代价 ...
- 【漫画】CAS原理分析!无锁原子类也能解决并发问题!
本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...
- 高效C++无锁队列实现-moodycamel::ConcurrentQueue
国外一牛人做的,支持多平台,支持多线程写.多线程读,并可指定读写token,转载过来. 感觉作者也时刻维护着他这个项目,我提了一些问题,每次都会及时得到答复,而且回复得非常认真仔细,非常赞! 链接地址 ...
- java 多线程12 : 无锁 实现CAS原子性操作----原子类
由于java 多线程11:volatile关键字该文讲道可以使用不带锁的情况也就是无锁使变量变成可见,这里就理解下如何在无锁的情况对线程变量进行CAS原子性及可见性操作 我们知道,在并发的环境下,要实 ...
- CAS原子操作实现无锁及性能分析
CAS原子操作实现无锁及性能分析 Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn.net/chen19870707 ...
- CAS无锁实现原理以及ABA问题
CAS(比较与交换,Compare and swap) 是一种有名的无锁算法.无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(N ...
随机推荐
- low到一定程度了
- core的生成
ubuntu12.04,默认无法生成core文件 输入ulimit -c 1024就ok了 列一下ulimit的参数,貌似这个命令是系统性能控制相关的,先不管了. 表 1. ulimit 参数说明 选 ...
- DOJO-dojox.grid.EnhancedGrid(带刷新函数,分页工具栏,复选框,行号等功能)
转自:http://biancheng.dnbcw.info/javascript/395865.html dojo.require("dojox.grid.EnhancedGrid&quo ...
- MyEclipse 自带的TomCat 新增部署的时候不显示 Deploy Location
项目总是报错,添了删,删了又添了N次以后,发现添加部署的时候,Deploy Location 没有值了,Deploy Location 没有值在自带的Tomcat上就无法用浏览器浏览(Open in ...
- java日志框架slf4j与log4j
日志记录自然是非常重要的,但恐怕能记住slf4j与log4j等日志框架配置的人就很少了,这个东西不难,只是配置好后很少会去动它,开发新项目一般也是从其他项目拷贝,或者参照文档 废话不多说,先说log4 ...
- TypeScript之基本数据类型
前言 最近项目很急,所以没有什么时间回答关于Xamarin.Android方面的问题,也有一段时间没有更新.主要是手头很缺人,如果有谁有兴趣加入我们的话,可以私聊我,这样我就能继续造福社区了,同时还有 ...
- Sql Server tempdb原理-缓存机制解析实践
Tempdb就像Sqlserver的临时仓库,各式各样的对象,数据在里面进行频繁计算,操作.大量的操作使得tempdb可能面临很大压力,tempdb中缓存的设计就是为了缓解这些压力.这次就为大家介绍下 ...
- android知识杂记(三)
记录项目中的android零碎知识点,用以备忘. 1.android 自定义权限 app可以自定义属于自己的权限: <permission android:description="s ...
- 《BI深入浅出》笔记
今年的项目涉及到BI的知识点,读了<商业智能深入浅出>,这本书是基于IBM的产品做的,基础知识部分讲的非常成体系.记下来做个备忘: 1. BI简介 1.1 实施方案 1)项目规划: 2)系 ...
- 004. Asp.Net Routing与MVC 之二: 请求如何激活Controller和Action
上篇讲到 请求到达 MvcRouteHandler ,并且透过 IRouteHandler.GetHttpHandler 获取到了真正的处理程序 MvcHandler 这次我们看看,MvcHandle ...