STL實現讀寫鎖
阿新 • • 發佈:2019-02-19
在這裡不考慮std::shared_mutex, 只用條件變數和std::mutex來實現。
分析讀寫鎖的邏輯:
讀鎖之間是不衝突的,無論多少個執行緒申請讀鎖,不需要等待。但是要想獲得寫鎖,就必須等所有的讀鎖全部釋放完畢。那麼怎麼知道所有的讀全部結束了呢?只能用一個int變數去記錄讀鎖的總數。這個變數變為0意味著所有的讀都結束了。所以,寫鎖的條件變數的寫法類似於:
while (readerCount != 0)
{
cv.wait(lock);
}
但這是不完善的,如果其他執行緒也在寫呢?寫鎖也必須等待寫操作結束。那麼寫鎖是否也需要int型來統計總數呢?不需要。bool型足矣。因此可以改為:
讀鎖只需要檢測是否有寫操作,遞增寫的個數:while (readerCount != 0 || writerUsed == true) { cv.wait(lock); }
while (writerUsed == true)
{
cv.wait(lock);
}
readerCount++;
讀鎖通知和寫鎖通知的時機也不同。讀鎖要等所有的讀全部結束的時候進行通知,寫鎖則是每個寫結束都要通知。
void unlockReader() { std::unique_lock<std::mutex> lock(m); readerCount--; if (readerCount == 0) { cv.notify_all(); } } void unlockWriter() { std::unique_lock<std::mutex> lock(m); writerUsed = false; cv.notify_all(); }
所有的程式碼:
class rwLock { public: void getReadLock() { std::unique_lock<std::mutex> lock(m); while (writerUsed == true) { cv.wait(lock); } readerCount++; } void getWriteLock() { std::unique_lock<std::mutex> lock(m); while (readerCount != 0 || writerUsed == true) { cv.wait(lock); } writerUsed = true; } void unlockReader() { std::unique_lock<std::mutex> lock(m); readerCount--; if (readerCount == 0) { cv.notify_all(); } } void unlockWriter() { std::unique_lock<std::mutex> lock(m); writerUsed = false; cv.notify_all(); } private: int readerCount = 0; bool writerUsed = false; std::mutex m; std::condition_variable cv; };