zoukankan      html  css  js  c++  java
  • c++中的原子操作

    1. c/c++标准中没有定义任何操作符为原子的,操作符是否原子和平台及编译器版本有关

    2. GCC提供了一组内建的原子操作,这些操作是以函数的形式提供的,这些函数不需要引用任何头文件

      2.1 对变量做某种操作,并且返回操作前的值,总共6个函数:

        type __sync_fetch_and_add (type *ptr, type value, ...)    加减运算 相当于  tmp = *ptr;  *ptr += value; return tmp;

        type __sync_fetch_and_sub (type *ptr, type value, ...)    加减运算 相当于  tmp = *ptr;  *ptr -= value; return tmp;

        type __sync_fetch_and_or (type *ptr, type value, ...)       逻辑运算 相当于  tmp = *ptr;  *ptr |= value; return tmp;

        type __sync_fetch_and_and (type *ptr, type value, ...)     逻辑运算 相当于  tmp = *ptr;  *ptr &= value; return tmp;

        type __sync_fetch_and_xor (type *ptr, type value, ...)     位运算 相当于  tmp = *ptr;  *ptr ^= value; return tmp;

        type __sync_fetch_and_nand (type *ptr, type value, ...)   位运算 相当于  tmp = *ptr; *ptr = ~(tmp & value); return tmp;

               注意,__sync_fetch_and_nand在GCC的4.4版本之前语义并非如此,而是 tmp = *ptr; *ptr = ~tmp & value; return tmp;

      2.2 对变量做某种操作,并且返回操作后的值,总共6个函数,和前面的6个函数完全类似:

        type __sync_add_and_fetch (type *ptr, type value, ...)

        type __sync_sub_and_fetch (type *ptr, type value, ...)

        type __sync_or_and_fetch (type *ptr, type value, ...)

        type __sync_and_and_fetch (type *ptr, type value, ...)

        type __sync_xor_and_fetch (type *ptr, type value, ...)

        type __sync_nand_and_fetch (type *ptr, type value, ...)

      2.3 把变量的值和某个值比较,如果相等就把变量的值设置为新的值,总共2个函数:

        bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)   

          返回是否相等,相当于

             if ( *ptr == oldval ) {*ptr = newval; return true;}

                              else {return false;}

        type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...)

          返回修改前的值,相当于

             tmp = *ptr 

             if ( *ptr == oldval ) { *ptr= newval; }

                              return tmp ;

      2.4 锁定测试-设置 及 解锁,总共2个函数: 

        type __sync_lock_test_and_set (type *ptr, type value, ...)

          把变量的值设置为新值,并返回设置前的值,相当于tmp = *ptr; return tmp

        void __sync_lock_release (type *ptr, ...)  

          把变量的值设置为0,相当于 *ptr = 0  通过查看汇编代码,可以看出这个函数使用了内存屏障,然后再把变量的值置为0

                这两个函数可以实现自旋锁

    3. 自旋锁的实现:boost实现如下,在spinlock_sync.hpp 

    class spinlock
    {
    public:
        int v_;
    public:
    
        bool try_lock()
        {
            int r = __sync_lock_test_and_set( &v_, 1 );
            return r == 0;
        }
    
        void lock()
        {
            for( unsigned k = 0; !try_lock(); ++k )
            {
                //等待一些指令周期
                boost::detail::yield( k );
            }
        }
    
        void unlock()
        {
            __sync_lock_release( &v_ );
        }
    };

    悲观锁和乐观锁
    独占锁是一种悲观锁,synchronized就是一种独占锁,它假设最坏的情况,并且只有在确保其它线程不会造成干扰的情况下执行,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一个更加有效的锁就是乐观锁。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。

    CAS操作
    Compare and Swap,比较并操作,CPU指令,在大多数处理器架构,包括IA32、Space中采用的都是CAS指令,CAS的语义是“我认为V的值应该为A,如果是,那么将V的值更新为B,否则不修改并告诉V的值实际为多少”,CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

  • 相关阅读:
    一些大佬博客里的个签
    后缀子串排序
    PAT 1024 Palindromic Number[难]
    dp训练
    字符串最长子串匹配dp矩阵[转载]
    最短路径并查集+Floyd[转载]
    素数牛客网[求大数内所有素数]
    sql server 的规格参数,限制等 (zz)
    sql server varchar(max), NVARCHAR(MAX), VARBINARY(MAX) (zz)
    Oracle Data Types NVARCHAR2 (zz)
  • 原文地址:https://www.cnblogs.com/liyulong1982/p/5500854.html
Copyright © 2011-2022 走看看