2015-03-03 94 views
0

參照RAII靜態互斥爲類的成員函數:C++ 11

我可以使用static mutex用於critical section爲:

#include <string> 
#include <mutex> 
#include <iostream> 
#include <fstream> 
#include <stdexcept> 

void write_to_file (const std::string & message) { 
    // mutex to protect file access 
    static std::mutex mutex; 

    // lock mutex before accessing file 
    std::lock_guard<std::mutex> lock(mutex); 

    // try to open file 
    std::ofstream file("example.txt"); 
    if (!file.is_open()) 
     throw std::runtime_error("unable to open file"); 

    // write message to file 
    file << message << std::endl; 

    // file will be closed 1st when leaving scope (regardless of exception) 
    // mutex will be unlocked 2nd (from lock destructor) when leaving 
    // scope (regardless of exception) 
} 

如果使用同樣的方法一類的成員函數,例如:

class Test{ 
    public: 
     void setI(int k) 
     { 
      static std::mutex mutex; 
      std::lock_guard<std::mutex> lock(mutex); 
      i=k; 
     } 

    private: 
     int i;  
}; 

以上方法的缺點和優點是什麼?

是更可取的使用方法如下:

class Test 
{ 
public: 
    void setI(int k) 
    { 
     std::lock_guard<std::mutex> lock(mutex); 
     i = k; 
    } 

private: 
    int i; 
    std::mutex mutex; 
}; 

何種方法來保證線程安全是更好?

+0

你正試圖用這些解決方案解決什麼問題? – 2015-03-03 09:12:58

回答

3

reference 1

「的成員函數聲明將保留函數調用之間的值。靜態變量將有超過所有實例只有一個副本」

無論您的解決方案是「有效的」,它實際上取決於你想實現什麼...成員函數內部

靜態互斥變量

該解決方案爲您提供了一個互斥對於類的所有實例。它可以有效地提供線程安全性,但是如果有很多對象散佈在不同的線程中,則可能不是性能的最佳選擇。 互斥量也僅限於單個函數,所以通常這會使實現不切實際。因此,靜態私有變量通常更好。內部類

私人互斥變量有了這個解決方案讓您根據您的類的實例一個互斥。爲您的課程提供線程安全以便多線程可以訪問它將是有效的。這通常是更優選的解決方案,因爲它允許不同的線程同時訪問不同的對象。 但是,這不足以保護您的班級的靜態成員的訪問。

大多數情況下,您希望在課堂中擁有私有的非靜態互斥鎖。

0

內部功能的靜態互斥似乎是有用的,只有(只),如果你想在這個函數訪問某些資源(只)。

如果你需要一些讀函數添加到類Test(如int getI() const;)明天,那麼你應該重構和setI功能和Test類。如果你使用互斥鎖作爲類的成員,那麼你只需要使用類似於setI的互斥體來編寫getI的代碼。