溫馨提示×

c++ 中的 set 怎處理并發訪問

c++
小樊
99
2024-11-29 18:13:02
欄目: 編程語言

在 C++ 中,std::set 是一個關聯容器,用于存儲唯一的元素。默認情況下,std::set 是線程不安全的,這意味著在多線程環境中使用它可能會導致數據競爭和不一致的狀態。為了在多線程環境中安全地使用 std::set,你可以采取以下幾種方法:

  1. 使用互斥鎖(std::mutex):

    在訪問和修改 std::set 時,使用 std::mutex 對象來保護數據。這可以確保在同一時間只有一個線程能夠訪問和修改 std::set。

    #include <iostream>
    #include <set>
    #include <mutex>
    #include <thread>
    
    std::set<int> my_set;
    std::mutex mtx;
    
    void insert(int value) {
        std::lock_guard<std::mutex> lock(mtx);
        my_set.insert(value);
    }
    
    void remove(int value) {
        std::lock_guard<std::mutex> lock(mtx);
        my_set.erase(value);
    }
    
    void print() {
        std::lock_guard<std::mutex> lock(mtx);
        for (const auto& item : my_set) {
            std::cout << item << " ";
        }
        std::cout << std::endl;
    }
    
    int main() {
        std::thread t1(insert, 1);
        std::thread t2(insert, 2);
        std::thread t3(remove, 1);
        std::thread t4(print);
    
        t1.join();
        t2.join();
        t3.join();
        t4.join();
    
        return 0;
    }
    
  2. 使用讀寫鎖(std::shared_mutex):

    如果你的程序中有很多讀取操作,但較少的寫入操作,那么可以使用 std::shared_mutex 來提高性能。std::shared_mutex 允許多個線程同時讀取數據,但在寫入數據時會阻止其他線程訪問。

    #include <iostream>
    #include <set>
    #include <shared_mutex>
    #include <thread>
    
    std::set<int> my_set;
    std::shared_mutex mtx;
    
    void insert(int value) {
        std::unique_lock<std::shared_mutex> lock(mtx);
        my_set.insert(value);
    }
    
    void remove(int value) {
        std::unique_lock<std::shared_mutex> lock(mtx);
        my_set.erase(value);
    }
    
    void print() {
        std::shared_lock<std::shared_mutex> lock(mtx);
        for (const auto& item : my_set) {
            std::cout << item << " ";
        }
        std::cout << std::endl;
    }
    
    int main() {
        std::thread t1(insert, 1);
        std::thread t2(insert, 2);
        std::thread t3(remove, 1);
        std::thread t4(print);
    
        t1.join();
        t2.join();
        t3.join();
        t4.join();
    
        return 0;
    }
    
  3. 使用線程安全的容器(C++20 及更高版本):

    C++20 引入了線程安全的容器,如 std::concurrent_set。這些容器在內部實現了適當的同步機制,因此可以在多線程環境中安全地使用。請注意,std::concurrent_set 并不是 C++ 標準庫的一部分,而是某些實現(如 GCC 和 Clang)提供的擴展。在使用之前,請確保你的編譯器和標準庫支持它。

    #include <iostream>
    #include <concurrent_set>
    #include <thread>
    
    std::concurrent_set<int> my_set;
    
    void insert(int value) {
        my_set.insert(value);
    }
    
    void remove(int value) {
        my_set.erase(value);
    }
    
    void print() {
        for (const auto& item : my_set) {
            std::cout << item << " ";
        }
        std::cout << std::endl;
    }
    
    int main() {
        std::thread t1(insert, 1);
        std::thread t2(insert, 2);
        std::thread t3(remove, 1);
        std::thread t4(print);
    
        t1.join();
        t2.join();
        t3.join();
        t4.join();
    
        return 0;
    }
    

總之,在多線程環境中使用 std::set 時,需要采取適當的同步機制來確保數據的一致性和安全性。你可以根據你的具體需求和場景選擇合適的方法。

0
亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女