zoukankan      html  css  js  c++  java
  • 【c++】atomic原子操作基本用法,模板函数。

    【转载】:https://owent.net/2012/611.html

    主要的函数如下:

     函数名     |     描述     |
    

    —————|————-|
    atomic_store | 保存非原子数据到原子数据结构 |
    atomic_load | 读取原子结构中的数据 |
    atomic_exchange | 保存非原子数据到原子数据结构,返回原来保存的数据 |
    atomic_fetch_add | 对原子结构中的数据做加操作 |
    atomic_fetch_sub/atomic_fetch_sub_explicit | 对原子结构中的数据做减操作 |
    atomic_fetch_and | 对原子结构中的数据逻辑与 |
    atomic_fetch_or | 对原子结构中的数据逻辑或 |
    atomic_fetch_xor | 对原子结构中的数据逻辑异或

    刚才提到了在原子操作时候的内存操作规则,内存操作规则主要是 std::memory_order,这是个枚举类型,里面包含着N多规则

       值           |    定义规则      |
    

    ——————–|—————-|
    memory_order_relaxed | 不保证顺序 |
    memory_order_consume | 类比生产者-消费者模型中的消费者读取动作(仅是读取,无计数器),保证该操作先于依赖于当前读取的数据(比如后面用到了这次读取的数据)不会被提前,但不保证其他读取操 作的顺序。仅对大多编译环境的多线程程序的编译优化过程有影响。 |
    memory_order_acquire | 类比生产者-消费者模型中的消费者读取动作(仅是读取,无计数器),保证在这个操作之后的所有操作不会被提前,同样对大多编译环境的多线程程序的编译优化过程有影响。 |
    memory_order_release | 类比生产者-消费者模型中的生产者创建动作(仅操作一个数据),保证这之前的操作不会被延后。 |
    memory_order_acq_rel | 同时包含memory_order_acquire和memory_order_release标记 |
    memory_order_seq_cst | 全部存取都按顺序执行,在多核系统上容易成为性能瓶颈 |

    在前面的原子操作的函数中,默认规则都是std::memory_order_seq_cst
    此外,atomic还有一些标记类型和测试操作,比较类似操作系统里的原子操作

    • std::atomic_flag : 标记类型
    • atomic_flag_test_and_set : 尝试设置为占用(原子操作)
    • atomic_flag_clear : 释放(原子操作)

      std::atomic_flag lock = ATOMIC_FLAG_INIT;
      
      void f(int n) {
      for(int cnt = 0; cnt < 100; ++cnt) {
          while(std::atomic_flag_test_and_set_explicit(&lock, std::memory_order_acquire));
          std::cout << "线程 " << n << std::endl;
          std::atomic_flag_clear_explicit(&lock, std::memory_order_release);
      }
      }
      
      int main() {
      std::atomic_int a;
      
      a.store(100);
      a.fetch_add(105);
      
      int i = a.load(std::memory_order_consume);
      
      printf("i => %d
      ", i);
      
      // 原子标记
      std::vector<std::thread> v;
      for (int n = 0; n < 10; ++n) {
          v.emplace_back(f, n);
      }
      for (auto t = v.begin(); t != v.end(); ++ t) {
          t->join();
      }
      
      return 0;
      }
  • 相关阅读:
    timeouts _ golang
    select.go
    channel directions _ golang
    channel synchronization _ golang
    channel _ buffering
    servlet:共享资源造成的线程冲突
    java:多线程的 共享资源冲突问题
    jsp:通过过滤器进行网页的资源管理
    jsp:通过Session控制登陆时间和内部页面的访问
    java:数据结构
  • 原文地址:https://www.cnblogs.com/cy1993/p/11498768.html
Copyright © 2011-2022 走看看