C++原子操作詳解

一、概述

C++原子操作是C++ 11標準引入的一個新的特性,用於確保多線程環境下的線程安全性。原子操作是一個不可分割的操作,能夠確保被多個線程同時訪問的變數能夠正確地同步。原子操作提供了一種高效的、易用的方式來處理共享數據。

二、原子變數

原子變數是一種特殊類型的變數,多個線程可以同時訪問它。原子變數的操作是原子的,即對一個原子變數的操作不可被打斷,也不會被其他線程所干擾。C++語言中定義了原子變數類型std::atomic,原子變數的操作可以通過std::atomic模板進行實現。

#include 
std::atomic counter{0}; //定義一個原子變數
counter++; //原子遞增操作

以上代碼定義了一個原子變數counter,並對其進行了遞增的操作。由於遞增操作是原子的,因此可以確保在多線程環境下,對counter的遞增操作不會被打斷。

三、原子操作類型

C++標準庫定義了幾種常用的原子操作類型,包括:

1. std::memory_order

std::memory_order是一個枚舉類型,用於指定內存序(memory order),即原子操作的執行順序。

enum class memory_order {
    relaxed, //鬆散的內存模型,不對內存序做任何保證
    consume,//對讀操作的順序做保證,對寫操作沒有任何保證
    acquire, //對讀操作的順序做保證,對寫操作沒有任何保證
    release, //對寫操作的順序做保證,對讀操作沒有任何保證
    acq_rel, //對讀/寫操作的順序做保證
    seq_cst  //對讀/寫操作和其他原子操作的順序做保證,嚴格的內存模型
};

2. std::atomic_flag

std::atomic_flag是一個特殊的原子變數類型,只能夠進行原子的測試和設置操作。std::atomic_flag類型可以用於實現自旋鎖。

#include 
std::atomic_flag lock = ATOMIC_FLAG_INIT; //初始化std::atomic_flag
lock.test_and_set(); //原子測試並設置操作
lock.clear(); //原子清除操作

3. std::atomic_bool

std::atomic_bool是一個原子布爾變數類型,可以進行原子的載入、存儲和交換操作。

#include 
std::atomic_bool flag{false}; //定義一個std::atomic_bool變數
bool temp = flag.exchange(true); //原子交換操作

4. std::atomic_integral

std::atomic_integral是一個原子整數變數類型,可以進行原子的載入、存儲、交換、遞增、遞減等操作。

#include 
std::atomic counter{0}; //定義一個std::atomic變數
counter++; //原子遞增操作
int temp = counter.fetch_add(10); //原子加法操作,並返回原先的值

四、原子操作的實現原理

原子操作的實現主要依賴於硬體體系結構提供的特殊指令(CPU指令)。這些特殊指令可以確保對共享變數的操作是原子的,即不可分割的,或者是具有一定的同步語義的。

在x86體系結構下,常用的原子操作命令包括:

  • lock cmpxchg:用於原子比較並交換操作
  • lock xchg:用於原子交換操作
  • lock add/sub:用於原子加法/減法操作

當CPU執行原子操作時,它會鎖定訪問操作的內存位置,並禁止其他CPU修改該位置的值。當原子操作完成後,CPU會釋放對該內存位置的鎖定,並允許其他CPU修改該位置的值。

五、多線程編程中的原子操作示例

下面的代碼示例演示了原子操作在多線程編程中的使用,其中包括std::atomic_bool的測試和設置操作、std::atomic_int的遞增操作,以及std::atomic_flag的設置和清除操作。

#include 
#include 
#include 

std::atomic_bool flag{false};
std::atomic_flag lock = ATOMIC_FLAG_INIT;
std::atomic_int counter{0};

void thread_func() {
    lock.test_and_set(); //原子測試並設置lock
    if (!flag) {
        flag = true; //原子設置flag
        std::cout << "Thread " << std::this_thread::get_id() << " sets the flag." << std::endl;
    }
    lock.clear(); //原子清除lock

    counter++; //原子遞增
    std::cout << "Thread " << std::this_thread::get_id() << " increases the counter to " << counter << "." << std::endl;
}

int main() {
    std::thread t1(thread_func);
    std::thread t2(thread_func);

    t1.join();
    t2.join();

    return 0;
}

運行該程序,可以看到兩個線程分別進行了原子操作,並保證了線程安全。

六、總結

本文對C++原子操作進行了詳細的介紹,包括原子變數、原子操作類型、原子操作的實現原理以及在多線程編程中的應用。藉助於原子操作,程序員可以輕鬆地處理共享數據的同步,從而提高程序的並發性能。

原創文章,作者:SOYJ,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/144124.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
SOYJ的頭像SOYJ
上一篇 2024-10-24 15:27
下一篇 2024-10-24 15:27

相關推薦

  • Python棧操作用法介紹

    如果你是一位Python開發工程師,那麼你必須掌握Python中的棧操作。在Python中,棧是一個容器,提供後進先出(LIFO)的原則。這篇文章將通過多個方面詳細地闡述Pytho…

    編程 2025-04-29
  • Python操作數組

    本文將從多個方面詳細介紹如何使用Python操作5個數組成的列表。 一、數組的定義 數組是一種用於存儲相同類型數據的數據結構。Python中的數組是通過列表來實現的,列表中可以存放…

    編程 2025-04-29
  • Python操作MySQL

    本文將從以下幾個方面對Python操作MySQL進行詳細闡述: 一、連接MySQL資料庫 在使用Python操作MySQL之前,我們需要先連接MySQL資料庫。在Python中,我…

    編程 2025-04-29
  • Python磁碟操作全方位解析

    本篇文章將從多個方面對Python磁碟操作進行詳細闡述,包括文件讀寫、文件夾創建、刪除、文件搜索與遍歷、文件重命名、移動、複製、文件許可權修改等常用操作。 一、文件讀寫操作 文件讀寫…

    編程 2025-04-29
  • Python代碼實現迴文數最少操作次數

    本文將介紹如何使用Python解決一道經典的迴文數問題:給定一個數n,按照一定規則對它進行若干次操作,使得n成為迴文數,求最少的操作次數。 一、問題分析 首先,我們需要了解迴文數的…

    編程 2025-04-29
  • Python元祖操作用法介紹

    本文將從多個方面對Python元祖的操作進行詳細闡述。包括:元祖定義及初始化、元祖遍歷、元祖切片、元祖合併及比較、元祖解包等內容。 一、元祖定義及初始化 元祖在Python中屬於序…

    編程 2025-04-29
  • 如何用Python對數據進行離散化操作

    數據離散化是指將連續的數據轉化為離散的數據,一般是用於數據挖掘和數據分析中,可以幫助我們更好的理解數據,從而更好地進行決策和分析。Python作為一種高效的編程語言,在數據處理和分…

    編程 2025-04-29
  • Python列表的讀寫操作

    本文將針對Python列表的讀取與寫入操作進行詳細的闡述,包括列表的基本操作、列表的增刪改查、列表切片、列表排序、列表反轉、列表拼接、列表複製等操作。 一、列表的基本操作 列表是P…

    編程 2025-04-29
  • Python序列的常用操作

    Python序列是程序中的重要工具,在數據分析、機器學習、圖像處理等很多領域都有廣泛的應用。Python序列分為三種:列表(list)、元組(tuple)和字元串(string)。…

    編程 2025-04-28
  • Python獲取Flutter上內容的方法及操作

    本文將從以下幾個方面介紹Python如何獲取Flutter上的內容: 一、獲取Flutter應用數據 使用Flutter提供的Platform Channel API可以很容易地獲…

    編程 2025-04-28

發表回復

登錄後才能評論