"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(&lt-> }

 void app_atomic_lock(app_atomic_lock_t * lt, long value)
 {
     u_int n, i;

     for (;; ) {

          && compare_and_swap(&lt->, value)) {
             return;
         }
         ; n < spin_num; n <<= ) {

             ; i < n; i++) {
                 cpu_pause();
             }

              && compare_and_swap(&lt->, value)) {
                 return;
             }
         }

         thread_yield();
     }
 }

 void app_atomic_unlock(app_atomic_lock_t * lt, long value)
 {
     compare_and_swap(&lt->);
 }
#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原子锁 高效自旋无锁的正确用法的更多相关文章

  1. JDK1.8 LongAdder 空间换时间: 比AtomicLong还高效的无锁实现

    我们知道,AtomicLong的实现方式是内部有个value 变量,当多线程并发自增,自减时,均通过CAS 指令从机器指令级别操作保证并发的原子性. // setup to use Unsafe.co ...

  2. CAS(Compare and Swap)无锁算法-学习笔记

    非阻塞同步算法与CAS(Compare and Swap)无锁算法 这篇问题对java的CAS讲的非常透彻! 锁的代价 1. 内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的 ...

  3. 非阻塞同步算法与CAS(Compare and Swap)无锁算法

    锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...

  4. 【Java并发编程】9、非阻塞同步算法与CAS(Compare and Swap)无锁算法

    转自:http://www.cnblogs.com/Mainz/p/3546347.html?utm_source=tuicool&utm_medium=referral 锁(lock)的代价 ...

  5. 【漫画】CAS原理分析!无锁原子类也能解决并发问题!

    本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...

  6. 高效C++无锁队列实现-moodycamel::ConcurrentQueue

    国外一牛人做的,支持多平台,支持多线程写.多线程读,并可指定读写token,转载过来. 感觉作者也时刻维护着他这个项目,我提了一些问题,每次都会及时得到答复,而且回复得非常认真仔细,非常赞! 链接地址 ...

  7. java 多线程12 : 无锁 实现CAS原子性操作----原子类

    由于java 多线程11:volatile关键字该文讲道可以使用不带锁的情况也就是无锁使变量变成可见,这里就理解下如何在无锁的情况对线程变量进行CAS原子性及可见性操作 我们知道,在并发的环境下,要实 ...

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

    CAS原子操作实现无锁及性能分析 Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn.net/chen19870707 ...

  9. CAS无锁实现原理以及ABA问题

    CAS(比较与交换,Compare and swap) 是一种有名的无锁算法.无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(N ...

随机推荐

  1. Last non-zero Digit in N!(阶乘最后非0位)

    Last non-zero Digit in N! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  2. rabbitmq集群安装

        在配置文件中配置集群没有成功,但是使用命令行成功了,以下是过程请参考.     场景:两台机器,一台是10.1.3.95 hostname为mq1,一台是10.1.3.96 hostname为 ...

  3. 对于git的认识

    对于git的认识,我只想说,我不会把他的概念复制下来在博客上再发一遍,我对于他的了解是代源码的开放编写.对于git我会在今后去认真的理解他,不是所谓的抄袭.不会的东西我会尽力去学习.

  4. zabbix3.x搭建(1)

    服务器端安装配置: 1).安装: yum -y install gcc gcc-c++ autoconf httpd php mysql mysql-server php-mysql httpd-ma ...

  5. 在docker里部署网络服务

    之前试着玩玩docker有一阵子了,今天算是头一回正式在docker里部署网络服务. 本来想和lxc差不多的东西那自然是手到擒来,没想到还是改了很多. 第一个遇到的问题是,远程连到docker宿主机干 ...

  6. Python札记 -- 使用easy_install进行模块/包管理

    今天在阅读以前项目代码时,发现里面使用的第三方模块的参数相当诡异,总是对不上.经过分析之后,发现是自己安装的第三方模块跟项目使用的版本不一致.在Python中进行模块/包管理的话,就不得不提到easy ...

  7. 深入理解Ember-Data特性(上)

    写在前面 最近比较忙,换了新工作还要学习很多全新的技术栈,并给自己找了很多借口来不去坚持写博客.常常具有讽刺意味的是,更多剩下的时间并没有利用而更多的是白白浪费,也许这就是青春吧,挥霍吧,这不是我想要 ...

  8. Web Essentials之JavaScript,TypeScript和CoffeeScript

    返回Web Essentials功能目录 一些Javascript功能也可以用于TypeScript. 本篇目录 功能 智能提示 TypeScript CoffeeScript 功能 JSHint J ...

  9. 图解集合3:CopyOnWriteArrayList

    初识CopyOnWriteArrayList 第一次见到CopyOnWriteArrayList,是在研究JDBC的时候,每一个数据库的Driver都是维护在一个CopyOnWriteArrayLis ...

  10. Java IO3:字节流

    流类 Java的流式输入/输出是建立在四个抽象类的基础上的:InputStream.OutputStream.Reader.Writer.它们用来创建具体的流式子类.尽管程序通过具体子类执行输入/输出 ...