首頁  >  文章  >  後端開發  >  C++類別設計中如何實作執行緒安全性?

C++類別設計中如何實作執行緒安全性?

WBOY
WBOY原創
2024-06-03 18:48:091027瀏覽

為了實現執行緒安全性,C++ 中有兩種方法:使用互斥量保護臨界區,允許一次只有一個執行緒存取。使用原子操作,以不可分割的方式執行操作,消除了並發存取問題。

C++類別設計中如何實作執行緒安全性?

C++ 類別設計中實作執行緒安全性

引言

在多在線程環境中,保證資料的線程安全性至關重要。 C++ 中有幾種方法可以實現這一點。本文將探討如何使用互斥和原子操作來設計線程安全的類別。

互斥量

互斥量是一種鎖定機制,它允許一次只能有一個執行緒存取臨界區。當一個執行緒進入臨界區時,它會取得互斥量的所有權。其他執行緒在試圖進入臨界區時會阻塞,直到該執行緒釋放互斥。

class ThreadSafeCounter {
private:
    std::mutex m_mutex;
    int m_count;

public:
    void increment() {
        std::lock_guard<std::mutex> lock(m_mutex);
        ++m_count;
    }

    int get() {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_count;
    }
};

在上面的範例中,increment()get() 方法都使用標準庫中的std::mutex 保護臨界區。當一個執行緒正在更新計數時,其他執行緒無法同時進入 increment() 方法。

原子操作

原子運算是一種特殊類型的操作,它以不可分割的方式執行。這意味著一次只能在單一執行緒中執行這些操作,從而消除了並發存取引發的問題。 C++11 中引入了 std::atomic 函式庫,它提供了原子操作的類別。

class ThreadSafeCounterAtomic {
private:
    std::atomic<int> m_count;

public:
    void increment() {
        ++m_count;
    }

    int get() {
        return m_count.load();
    }
};

在本例中,m_count 是一個原子整數,可以安全地從多個執行緒中進行增量和取得。 std::atomic<int>::load()</int> 方法以線程安全的方式取得原子整數的值。

實戰案例

考慮一個需要從多個執行緒並行更新的共享計數器的範例:

#include <thread>

int main() {
    std::unique_ptr<ThreadSafeCounter> counter = std::make_unique<ThreadSafeCounter>();

    std::vector<std::thread> threads(10);
    for (auto& thread : threads) {
        thread = std::thread([&] {
            for (int i = 0; i < 1000000; ++i) {
                counter->increment();
            }
        });
    }

    for (auto& thread : threads) {
        thread.join();
    }

    std::cout << "最终计数:" << counter->get() << std::endl;
}

在這個程式中,我們從10個執行緒並行更新計數器,然後在主執行緒中列印最終計數。互斥量可確保計數器在任何時刻最多只能由一個執行緒更新,從而確保執行緒安全性。

結論

透過使用互斥和原子操作,可以設計執行緒安全的 C++ 類別。互斥量適用於保護需要串行存取的臨界區,而原子操作適用於無需串行存取且可以原子方式執行的操作。

以上是C++類別設計中如何實作執行緒安全性?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn