C++ 17 的 Read/Write Lock 使用方法

開發看盤軟體時,資料通常是讀取的頻率大於寫入的頻率,例如收到一筆股價 Tick,寫入資料結構一次,然後在多種圖形顯示,也就是讀取多次。

在 C++ 17 之前,要使用 Read/Write Lock 只能自己實現或使用系統提供的 API,但現在情況有所改變,以下就是 C++ 17 讀寫鎖的使用方法:

#include <shared_mutex>

std::shared_mutex g_mutex;

Write Lock 這樣寫

std::unique_lock<std::shared_mutex> wLock(g_mutex);

Read Lock 這樣寫

std::shared_lock<std::shared_mutex> rLock(g_mutex);

可以發現 C++ 17 Read/Write lock 的使用就是這麼平易近人且直觀。

但有一個地方要注意,一般我們都是在成員函式裡使用 std::shared_mutex,所以會將它宣告為成員變數,另外我們會用 Set function 來改變成員變數,Get function 讀取成員變數,所以會宣告 Get function 為 const 成員函式,例子如下:

#include <shared_mutex>

class CStockInfo
{
public:
	void SetPrice(double dPrice)
	{
		std::unique_lock<std::shared_mutex> wLock(m_mutex);
		m_dPrice = dPrice;
	}

	double GetPrice() const
	{
		std::shared_lock<std::shared_mutex> rLock(m_mutex);
		return m_dPrice;
	}

private:
	double m_dPrice;
	std::shared_mutex m_mutex;
};

但此時編譯程式會發現編譯器在 GetPrice 報錯,因為成員函式宣告為 const,此時不明就裡的程式設計師會乾脆將 const 拿掉,這是錯誤的,正確的做法是在宣告 std::shared_mutex 變數前加上 mutable,如此就告訴編譯器它是邏輯上的常量了。

#include <shared_mutex>

class CStockInfo
{
...
private:
	double m_dPrice;
	mutable std::shared_mutex m_mutex; // 宣告為 mutable