谷歌数据竞争检测工具ThreadSanitizer代码阅读记录——atomic相关文件

这篇博客详细记录了阅读谷歌数据竞争检测工具ThreadSanitizer中atomic相关文件的过程,涉及gcc-9.1.0的sanitizer_common库。文章讨论了内存序列枚举、原子性结构体、指针定义、预编译选择性包含头文件,以及在clang中对__sync系列原子操作的重新实现。同时,解释了atomic_thread_fence函数和DCHECK()断言的用途,以及在x86和其他平台上原子操作的实现细节,如proc_yield、atomic_load和atomic_store。
摘要由CSDN通过智能技术生成
gcc-9.1.0\libsanitizer\sanitizer_common\sanitizer_atomic.h
  • 文件有一个内存序列的枚举类型
    enum memory_order {
      memory_order_relaxed = 1 << 0,
      memory_order_consume = 1 << 1,
      memory_order_acquire = 1 << 2,
      memory_order_release = 1 << 3,
      memory_order_acq_rel = 1 << 4,
      memory_order_seq_cst = 1 << 5
    };
  • 定义了多个不同位数的原子性结构体,如atomic_uint32_t表示原子性无符号32位整形。
  • 定义了原子性的指针,指针大小由系统的位数决定。
  • 使用预编译选择性包含了头文件
#if defined(__clang__) || defined(__GNUC__)
# include "sanitizer_atomic_clang.h"
#elif defined(_MSC_VER)
# include "sanitizer_atomic_msvc.h"
#else
# error "Unsupported compiler"
#endif
  • 定义了两个模板函数atomic_load_relaxed和atomic_store_relaxed,具体实现与前面预编译包含的头文件有关
如果你希望通过信号量记录某个数据的变化情况,可以使用 std::atomic 类型和 std::condition_variable 类型来实现。下面是一个简单的 C++ 代码示例: ```c++ #include <iostream> #include <thread> #include <mutex> #include <condition_variable> #include <atomic> std::atomic<int> data{0}; std::mutex mutex_; std::condition_variable cond_; void producer() { for (int i = 0; i < 10; ++i) { std::unique_lock<std::mutex> lock(mutex_); data.store(i); cond_.notify_all(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } void consumer() { int local_data = -1; while (true) { std::unique_lock<std::mutex> lock(mutex_); cond_.wait(lock, []{ return data.load() != -1; }); local_data = data.load(); data.store(-1); lock.unlock(); std::cout << "Consumed data: " << local_data << std::endl; if (local_data == 9) { break; } } } int main() { std::thread t1(producer); std::thread t2(consumer); t1.join(); t2.join(); return 0; } ``` 这个代码示例中,我们使用 std::atomic<int> 类型来存储数据,这是一个线程安全的数据类型。在生产者线程中,我们通过调用 data.store() 方法来更新数据,并通过调用 cond_.notify_all() 方法来通知消费者线程。在消费者线程中,我们使用 std::condition_variable 类型来等待数据的变化,并使用 cond_.wait() 方法来等待通知。在等待期间,消费者线程会释放锁,以便生产者线程可以更新数据。当消费者线程接收到通知后,它会重新获取锁,并使用 data.load() 方法来获取数据。由于使用了 std::atomic 类型,数据的读取和写入都是原子的,因此不需要额外的锁来保护数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值