2016-11-17 81 views
0

是否有線程安全類成員變量的C++語言功能?快速搜索或兩個都沒有透露,但我認爲這很簡單,並提出了這個解決方案。是否有線程安全類變量的C++標準?

template <class T> 
class ThreadSafeVar 
{ 
private: 
    T safeVar; 
    std::mutex accessMutex; 

public: 
    ThreadSafeVar(T initialValue) { safeVar = initialValue; } 
    ThreadSafeVar<T>& operator=(const T &source) { set(source); return *this; } 
    ThreadSafeVar<T>& operator=(ThreadSafeVar<T> &source) { set(source.get()); return *this; }; 

    void set(T newValue) 
    { 
     std::lock_guard<std::mutex> lock(accessMutex); 
     safeVar = newValue; 
    }; 

    T const get(void) 
    { 
     std::lock_guard<std::mutex> lock(accessMutex); 
     return safeVar; 
    }; 
}; 

此解決方案是否有任何問題(可能的死鎖等)? C++是否已經有了這樣的方法?

+0

對於TriviallyCopyable類型,std :: atomic 提供了set,​​get和exchange方法。 –

回答

0

你的代碼沒有問題。對於trivially可複製類型有std :: atomic。

0

請參閱std::atomicstd::memory_order

以下是一個示例,您可以使用g++ -std=c++ atomic_example.cpp來嘗試。

#include <atomic> 
#include <iostream> 
#include <thread> 

class ThreadSafeVar { 
public: 
    ThreadSafeVar() { var_.store(0, std::memory_order::memory_order_relaxed); } 
    ~ThreadSafeVar() {} 

    void Add() { var_.fetch_add(1, std::memory_order::memory_order_acquire); } 

    long Get() { return var_.load(std::memory_order_acquire); } 

private: 
    std::atomic<long> var_; 
}; 

void Foo(ThreadSafeVar& var) { 
    long i = 0; 
    while (i++ < (1l << 20)) { 
    var.Add(); 
    } 
} 

int main(int argc, char* argv[]) { 
    ThreadSafeVar var; 
    std::thread thr1 = std::thread(Foo, std::ref(var)); 
    std::thread thr2 = std::thread(Foo, std::ref(var)); 
    thr1.join(); 
    thr2.join(); 
    std::cout << "var = " << var.Get() << "\n"; 
    return 0; 
}