關(guān)于讀寫鎖,有個(gè)線程在讀,能寫嗎?有個(gè)線程在寫,能讀嗎?
引言
在多線程編程中,讀寫鎖(Read-Write Lock)是一種常見的同步機(jī)制,用于解決多個(gè)線程同時(shí)訪問共享資源的問題。
讀寫鎖
讀-寫問題分析
在回答上述問題之前,我們需要理解兩種不同類型的線程操作:讀操作和寫操作?!?/p>
讀操作是無副作用的操作,它只從共享資源中獲取信息而不改變其狀態(tài)?!?/p>
寫操作是有副作用的操作,它會(huì)修改共享資源的狀態(tài)?!?/p>
當(dāng)有多個(gè)線程同時(shí)訪問共享資源時(shí),我們需要確保以下幾點(diǎn):
一致性:所有線程看到的數(shù)據(jù)是一致的。
原子性:復(fù)合操作被視為不可分割的整體,要么全部完成,要么全部不發(fā)生?!?/p>
隔離性:線程間的操作相互獨(dú)立,不會(huì)互相干擾。
持久性:一旦寫操作完成,結(jié)果必須持久化,即使系統(tǒng)崩潰也能恢復(fù)。
讀寫鎖是一種特殊的鎖機(jī)制,它把對(duì)共享資源的訪問分為讀操作和寫操作:
讀操作(共享鎖):允許多個(gè)線程同時(shí)讀取資源,如果當(dāng)前沒有寫者,讀鎖可以被多個(gè)讀者持有。當(dāng)有寫者嘗試獲取鎖時(shí),所有新的讀請(qǐng)求都會(huì)被阻塞,直到寫者釋放了鎖?!?/p>
寫操作(排他鎖):只允許一個(gè)線程寫入資源,寫鎖是排他的,當(dāng)一個(gè)線程持有寫鎖時(shí),其他任何線程(無論是讀者還是寫者)都不能訪問資源。只有當(dāng)寫鎖被釋放后,其他線程才能繼續(xù)?!?/p>
讀寫鎖的規(guī)則:
讀-讀:允許并發(fā)
讀-寫:互斥
寫-讀:互斥
寫-寫:互斥
C++讀寫鎖實(shí)現(xiàn)
C++17引入了std::shared_mutex,這是標(biāo)準(zhǔn)庫提供的讀寫鎖實(shí)現(xiàn):
#include <shared_mutex>
#include <thread>
#include <iostream>
#include <vector>
#include <chrono>
class ThreadSafeCounter {
private:
mutable std::shared_mutex mutex_;
int value_ = 0;
public:
// 寫操作 - 使用獨(dú)占鎖
void increment() {
std::unique_lock<std::shared_mutex> lock(mutex_);
value_++;
}
// 讀操作 - 使用共享鎖
int get() const {
std::shared_lock<std::shared_mutex> lock(mutex_);
return value_;
}
};
在這個(gè)例子中,std::shared_lock 用于保護(hù)讀操作,而 std::unique_lock 用于保護(hù)寫操作。讀者可以同時(shí)訪問共享數(shù)據(jù),而寫者則需要獨(dú)占訪問?!?/p>
結(jié)論
有個(gè)線程在讀,能寫嗎?不能。如果有線程正在讀取數(shù)據(jù),那么寫操作應(yīng)該被推遲,直到所有的讀操作完成。這是為了確保寫操作不會(huì)破壞讀者看到的一致性視圖。
有個(gè)線程在寫,能讀嗎?也不能。如果一個(gè)線程正在寫入數(shù)據(jù),那么所有其他線程(包括讀者和寫者)都必須等待,直到寫操作完成。這是為了確保寫操作的原子性和隔離性。