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 ...
随机推荐
- JS动态级联菜单
JS动态级联菜单是前端常用的一个功能,特此抽时间研究了下,附上代码 <html> <head> <meta charset="utf-8" /> ...
- [XAF] How to represent an enumeration property via a drop-down box with check boxes
https://www.devexpress.com/Support/Center/Example/Details/E689
- MyEclipse 常用操作
1.使用JREBEL插件包实现myeclipse修改类文件后无须重启 在Myeclipse中的window-preferences(搜索tomcat)->然后到tomcatx.x下的-jdk中配 ...
- 浅谈 facebook .net sdk 应用
今天看了一篇非常好的文章,就放在这里与大家分享一下,顺便也给自己留一份.这段时间一直在学习MVC,另外如果大家有什么好的建议或者学习的地方,也请告知一下,谢谢. 这篇主要介绍如何应用facebook ...
- VS2008 Pocket PC 2003 SE仿真程序上网设置
设置大体分为3个步骤:Microsoft ActiveSync安装配置.Pocket PC 2003 SE仿真程序配置.Pocket PC 2003连接到Microsoft ActiveSync. 1 ...
- nginx+winsw windows服务
1.下载Nginx:http://nginx.org/en/download.html 2.下载winsw配置包:http://files.cnblogs.com/files/objecttozero ...
- 【腾讯Bugly干货分享】腾讯验证码的十二年
本文来自于腾讯bugly开发者社区,未经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/581301b146dfb1456904df8d Dev Club 是一个交流移动 ...
- Win10 UWP开发中的重复性静态UI绘制小技巧 2
小技巧1 地址:http://www.cnblogs.com/ms-uap/p/4641419.html 介绍 我们在上一篇博文中展示了通过Shape.Stroke族属性实现静态重复性UI绘制,使得U ...
- 细说angular Form addControl方法
在本篇博文中,我们将接触angular的验证.angular的验证是由form 指令和ngModel协调完成的.今天博主在这里想要说的是在验证在的一种特殊情况,当验证控件没有没有name属性这是不会被 ...
- .net程序单元测试介绍
什么是单元测试?为什么要进行单元测试?如需要进一步了解,请移步维基百科. 关于.net程序单元测试的文章,网上已经有很多,但我相信我写的这篇文章的内容是独特的,因为我在网上找了很久,都没找到关于Str ...