原子操作实现

Dear 丶 2022-08-05 10:27 294阅读 0赞

原子操作实现

关于CAS等原子操作:
在开始说无锁队列之前,我们需要知道一个很重要的技术就是CAS操作——Compare & Set,或是 Compare & Swap,现在几乎所有的CPU指令都支持CAS的原子操作,X86下对应的是CMPXCHG 汇编指令。有了这个原子操作,我们就可以用其来实现各种无锁(lock free)的数据结构。

这个操作用C语言来描述就是下面这个样子:
看一看内存*reg里的值是不是oldval,如果是的话,则对其赋值newval。

int compare_and_swap (int* reg, int oldval, int newval)
{
int old_reg_val = *reg;
if (old_reg_val == oldval)
*reg = newval;
return old_reg_val;
}
这个操作可以变种为返回bool值的形式(返回 bool值的好处在于,可以调用者知道有没有更新成功):
bool compare_and_swap (int *accum, int *dest, int newval)
{
if ( *accum == *dest )
{
*dest = newval;
return true;
}
return false;
}

// 原子自增操作

type __sync_fetch_and_add (type *ptr, type value)

// 原子比较和交换(设置)操作

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

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

// 原子赋值操作

type __sync_lock_test_and_set (type *ptr, type value)

使用这些原子性操作,编译的时候需要加-march=cpu-type

无锁队列实现

http://coolshell.cn/articles/8239. html

muduo上的一个实现:

  1. #ifndef MUDUO_BASE_ATOMIC_H
  2. #define MUDUO_BASE_ATOMIC_H
  3. #include <boost/noncopyable.hpp>
  4. #include <stdint.h>
  5. namespace muduo
  6. {
  7. namespace detail
  8. {
  9. template<typename T>
  10. class AtomicIntegerT : boost::noncopyable
  11. {
  12. public:
  13. AtomicIntegerT()
  14. : value_(0)
  15. {
  16. }
  17. // uncomment if you need copying and assignment
  18. //
  19. // AtomicIntegerT(const AtomicIntegerT& that)
  20. // : value_(that.get())
  21. // {}
  22. //
  23. // AtomicIntegerT& operator=(const AtomicIntegerT& that)
  24. // {
  25. // getAndSet(that.get());
  26. // return *this;
  27. // }
  28. T get()
  29. {
  30. return __sync_val_compare_and_swap(&value_, 0, 0); //如果ptr所指向的内存中的数据等于oldval,则设置其为newval, 返回true。
  31. }
  32. T getAndAdd(T x)
  33. {
  34. return __sync_fetch_and_add(&value_, x); // 返回值为*value_, value_的值变为value_ + x.
  35. }
  36. T addAndGet(T x)
  37. {
  38. return getAndAdd(x) + x;
  39. }
  40. T incrementAndGet()
  41. {
  42. return addAndGet(1);
  43. }
  44. T decrementAndGet()
  45. {
  46. return addAndGet(-1);
  47. }
  48. void add(T x)
  49. {
  50. getAndAdd(x);
  51. }
  52. void increment()
  53. {
  54. incrementAndGet();
  55. }
  56. void decrement()
  57. {
  58. decrementAndGet();
  59. }
  60. T getAndSet(T newValue)
  61. {
  62. return __sync_lock_test_and_set(&value_, newValue); // 将*ptr设为value并返回*ptr操作之前的值。
  63. }
  64. private:
  65. volatile T value_;
  66. };
  67. }
  68. typedef detail::AtomicIntegerT<int32_t> AtomicInt32;
  69. typedef detail::AtomicIntegerT<int64_t> AtomicInt64;
  70. }
  71. #endif // MUDUO_BASE_ATOMIC_H</span>

发表评论

表情:
评论列表 (有 0 条评论,294人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java如何实现原子操作

    在Java中可以通过锁和循环CAS的方式来实现原子操作。 (1)使用循环CAS实现原子操作 ​ JVM中的CAS操作正是利用了处理器提供的CMPXCHG指令实现的。自旋CA

    相关 原子操作实现

    原子操作实现 关于CAS等原子操作:          在开始说无锁队列之前,我们需要知道一个很重要的技术就是CAS操作——Compare & Set,或是 C

    相关 原子操作

     原子操作 在多线程编程中,访问同一个变量时需要利用锁来限制同一个时刻只有一个线程访问,否则会遇到未知的错误,最常用的锁有信号量、线程锁。系统也提供了一些原子操作来实现

    相关 原子操作

    原子操作指的是在执行过程中不会被别的代码中断的操作 位和整型变量原子操作依赖底层CPU的原子操作来实现,因此所有这些函数都与CPU架构密切相关 整型原子操作 定义