zoukankan      html  css  js  c++  java
  • CPU的CAS操作

     https://blog.csdn.net/qq_35492857/article/details/78471032

    https://www.cnblogs.com/gdjdsjh/p/5076815.html    CAS操作

    https://blog.csdn.net/kkfdsa132/article/details/5474013   c#之线程同步浅析(1)-----轻量级同步Interlocked

    CAS(compare and wasp)比较并操作,解决多线程并行情况下使用锁造成性能损耗的机制。

    所以在写CAS之前先说说基于锁的编程的都有哪些缺点。

    以下内容参考网上现有资料。

    锁的缺点:

    多线程编程中 我们一般会使用各种锁来确保对共享资源的访问和操作,需要共享的数据要对它的访问串行化。

    修改共享数据的操作必须以原子操作的形式出现才能保证不被其它线程破坏相应数据。

    锁这种机制无法彻底避免以下几点问题:

    1、锁引起线程的阻塞,对于没有能占用到锁的线程或者进程将会一直等待锁的占有者释放资源后才能继续。

    2、申请和释放锁的操作增加了很多访问共享资源的消耗。

    3、锁不能很好的避免编程开发者设计实现的程序出现死锁或者活锁可能

    4、优先级反转和所护送怪现象

    5、难以调试

    -------------以上几点来自http://blog.csdn.net/liusuper2088/article/details/41047501

    无锁编程:

    不用锁的情况下实现多线程间的同步,即非阻塞同步。

    非阻塞同步分三个级别:

    1、wait-free

         整个操作保证每个线程在有限步骤下完成

         保证系统及吞吐以及无线程饥饿

         理想模式

    2、lock-free

         允许个别线程饥饿,保证系统级吞吐量

         确保至少有一个线程能继续执行

    3、obstruction-free

         任何时刻一个线程被隔离为一个事务进行执行(其它线程suspended)且在有限步骤内完成

         一旦发现数据被修改,回滚

         也叫乐观锁

         lock-free必然是obstruction-free的

    -------以上内容来自http://www.cnblogs.com/caca/p/lock-free_CAS_ABA.html

    悲观锁和乐观锁:

    1、悲观锁:独占和排他,所以在数据处理过程中将数据处于锁定状态。

         传统的关系型数据库就用了很多这种锁:行锁、表锁、读写锁都是操作前上锁。会加大长事务的开销。

    2、乐观锁:修改数据不会上锁但是更新时会判断期间又没有发生数据的更新。

         避免长事务开销,但可能会造成脏数据。

         基于版本记录机制实现。

    CAS:

    CAS原语有三个操作数——内存位置(V)、预期原值(A)、新值(B)。

    若内存位置与预期原值匹配则处理器将该位置更新为新值。否则不做操作。

    无论何种情况都会在CAS指令之前返回该位置值。这个过程是原子性的。

    使用CAS会造成ABA问题。

    CAS是项乐观锁技术,若有多个线程试图同时更新一个变量,只有一个线程能更新,其它线程失败,失败的线程仍可再次尝试。

    CAS可以通过乐观锁模式实现自增自减的高并发效率。

    ABA问题:

    如果另一个线程修改V值,假设原来是A,先修改成B后又修改回A,当前线程的CAS操作无法分辨V是否变化。

    解决方法:在CAS操作时,带上版本号,每修改一次,版本号+1,之后比较原值的时候还要比较版本号

    通过CAS实现一个无锁队列

             无锁队列的链表实现:

    EnQueue(x)//进队

    {

           //准备新加入的结点数据

           q = new record();

           q->value = x;

           q->next = NULL;

           p = tail;//链表尾指针

           oldp = p;

           do

          {//开始loop cas

                  while(p->next != NULL)//防止进行cas(tail,oldp,q)操作的线程挂掉引起死循环

                          p = p->next;

          }

           while(CAS(p->next,NULL,q)!=true);//如果没有吧结点链在尾指针上,再试

           CAS(tail,oldp,q);//置尾结点

    }

    DeQueue()//出队

    {

           do

          {

                   p = head;

                   if(p->next == NULL)

                  {

                         return ERR_EMPTY_QUEUE;

                  }

            while(CAS(head,p,p->next)!=true);

            return p->next->value;

          }

    }

    ------------无锁队列部分来自《Implementing Lock-Free Queues》。

    http://blog.csdn.net/liusuper2088/article/details/41047501=。=这篇说的更详细一点

               

  • 相关阅读:
    Linux 安装SonarQube
    Linux 安装postgresql
    如何为chrome浏览器设置socks5代理
    echarts tab切换宽度变为100px解决方案
    将url参数转为对象
    一行js代码实现时间戳转时间格式
    解决问题的方法论
    李笑来的幻灯课
    随便写写(最近更新于2021/07/18早)
    谈谈装系统这件事
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/10672755.html
Copyright © 2011-2022 走看看