網站首頁 編程語言 正文
一、說明
Boost.Atomic 提供類 boost::atomic,可用于創建原子變量。它們被稱為原子變量,因為所有訪問都是原子的。 Boost.Atomic 用于多線程程序,當在一個線程中訪問變量不應被訪問相同變量的另一個線程中斷時。如果沒有 boost::atomic,從多個線程訪問共享變量的嘗試將需要與鎖同步。
boost::atomic 取決于支持原子變量訪問的目標平臺。否則,boost::atomic 使用鎖。該庫允許您檢測目標平臺是否支持原子變量訪問。
如果您的開發環境支持 C++11,則不需要 Boost.Atomic。 C++11 標準庫提供了一個頭文件 atomic,它定義了與 Boost.Atomic 相同的功能。例如,您會發現一個名為 std::atomic 的類。
Boost.Atomic 支持與標準庫大致相同的功能。雖然一些函數在 Boost.Atomic 中被重載,但它們在標準庫中可能有不同的名稱。標準庫還提供了一些 Boost.Atomic 中缺少的函數,例如 std::atomic_init() 和 std::kill_dependency()。
二、示例和代碼
示例 45.1。使用 boost::atomic
Boost.Atomic
#include <boost/atomic.hpp>
#include <thread>
#include <iostream>
boost::atomic<int> a{ 0 };
void thread()
{
++a;
}
void thread_s()
{
std::cout << "Hello Thread" << a << '\n';
}
int main()
{
std::thread t1{ thread };
std::thread t2{ thread };
std::thread t3{ thread_s };
std::thread t4{ thread_s };
t1.join();
t2.join();
t3.join();
t4.join();
std::cout << a << '\n';
}
Example45.1
示例 45.1 使用兩個線程來遞增 int 變量 a。該示例使用 boost::atomic 代替鎖來對 a 進行原子訪問。該示例將 2 寫入標準輸出。
boost::atomic 之所以有效,是因為一些處理器支持對變量的原子訪問。如果增加一個 int 變量是一個原子操作,則不需要鎖。如果此示例在無法將變量遞增為原子操作的平臺上運行,則 boost::atomic 使用鎖。
示例 45.2。 boost::atomic 帶鎖或不帶鎖
#include <boost/atomic.hpp>
#include <iostream>
int main()
{
std::cout.setf(std::ios::boolalpha);
boost::atomic<short> s;
std::cout << s.is_lock_free() << '\n';
boost::atomic<int> i;
std::cout << i.is_lock_free() << '\n';
boost::atomic<long> l;
std::cout << l.is_lock_free() << '\n';
}
您可以在原子變量上調用 is_lock_free() 來檢查是否在沒有鎖的情況下訪問該變量。如果您在 Intel x86 處理器上運行示例,它會顯示 true 三次。如果您在沒有對 short、int 和 long 變量進行無鎖訪問的處理器上運行它,則會顯示 false。
Boost.Atomic 提供了 BOOST_ATOMIC_INT_LOCK_FREE 和 BOOST_ATOMIC_LONG_LOCK_FREE 宏來在編譯時檢查哪些數據類型支持無鎖訪問。
示例 45.2 僅使用整型數據類型。您不應將 boost::atomic 與 std::string 或 std::vector 等類一起使用。 Boost.Atomic 支持整數、指針、布爾值 (bool) 和普通類。整數類型的示例包括 short、int 和 long。普通類定義可以使用 std::memcpy() 復制的對象。
示例 45.3。 boost::atomic 和 boost::memory_order_seq_cst
#include <boost/atomic.hpp>
#include <thread>
#include <iostream>
boost::atomic<int> a{0};
void thread()
{
a.fetch_add(1, boost::memory_order_seq_cst);
}
int main()
{
std::thread t1{thread};
std::thread t2{thread};
t1.join();
t2.join();
std::cout << a << '\n';
}
Example45.3E
示例 45.3 增加了兩次——這次不是使用 operator++,而是調用 fetch_add()。成員函數 fetch_add() 可以采用兩個參數:a 應該遞增的數字和內存順序。
內存順序指定內存訪問操作必須發生的順序。默認情況下,這個順序是不確定的,不依賴于代碼行的順序。只要程序表現得好像內存訪問操作是按源代碼順序執行的,編譯器和處理器就可以更改順序。此規則僅適用于線程。如果使用多個線程,內存訪問順序的變化會導致程序運行錯誤。 Boost.Atomic 支持在訪問變量時指定內存順序,以確保內存訪問在多線程程序中以所需的順序發生。
注意
指定內存順序可優化性能,但會增加復雜性并使編寫正確代碼變得更加困難。因此,在實踐中,您應該有充分的理由使用內存順序。
示例 45.3 使用內存順序 boost::memory_order_seq_cst 將 a 遞增 1。內存順序代表順序一致性。這是最嚴格的內存順序。在 fetch_add() 調用之前出現的所有內存訪問必須在執行此成員函數之前發生。在 fetch_add() 調用之后出現的所有內存訪問都必須在執行此成員函數之后發生。編譯器和處理器可以在調用 fetch_add() 之前和之后重新排序內存訪問,但它們不得將內存訪問從調用 fetch_add() 之前移動到調用之后,反之亦然。 boost::memory_order_seq_cst 是雙向內存訪問的嚴格邊界。
原文鏈接:https://yamagota.blog.csdn.net/article/details/127920647
相關推薦
- 2023-03-01 多語言切換在Androidx失效的踩坑解決記錄_Android
- 2022-10-14 Sklearn中的二分類模型可以進行多分類的原理
- 2022-07-16 mybatis的相同攔截器—切面執行的順序
- 2022-07-29 C++超詳細講解邏輯操作符_C 語言
- 2022-06-07 nlp自然語言處理學習CBOW模型類實現示例解析_python
- 2022-11-06 Android?菜單欄DIY實現效果詳解_Android
- 2022-11-15 python運行cmd命令行的3種方法總結_python
- 2023-01-13 Python?CNN卷積神經網絡實戰教程深入講解_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支