日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++读写锁

發(fā)布時間:2024/8/23 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++读写锁 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? ?讀寫鎖實際是一種特殊的自旋鎖,它把對共享資源的訪問者劃分成讀者和寫者,讀者只對共享資源進(jìn)行讀訪問,寫者則需要對共享資源進(jìn)行寫操作。

讀寫鎖實際是一種特殊的自旋鎖,它把對共享資源的訪問者劃分成讀者和寫者,讀者只對共享資源進(jìn)行讀訪問,寫者則需要對共享資源進(jìn)行寫操作。這種鎖相對于自旋鎖而言,能提高并發(fā)性,因為在多處理器系統(tǒng)中,它允許同時有多個讀者來訪問共享資源,最大可能的讀者數(shù)為實際的邏輯CPU數(shù)。寫者是排他性的,一個讀寫鎖同時只能有一個寫者或多個讀者(與CPU數(shù)相關(guān)),但不能同時既有讀者又有寫者。 在讀寫鎖保持期間也是搶占失效的。 如果讀寫鎖當(dāng)前沒有讀者,也沒有寫者,那么寫者可以立刻獲得讀寫鎖,否則它必須自旋在那里,直到?jīng)]有任何寫者或讀者。如果讀寫鎖沒有寫者,那么讀者可以立即獲得該讀寫鎖,否則讀者必須自旋在那里,直到寫者釋放該讀寫鎖。 ? ? ? ? 一次只有一個線程可以占有寫模式的讀寫鎖, 但是可以有多個線程同時占有讀模式的讀寫鎖. 正是因為這個特性, 當(dāng)讀寫鎖是寫加鎖狀態(tài)時, 在這個鎖被解鎖之前, 所有試圖對這個鎖加鎖的線程都會被阻塞. 當(dāng)讀寫鎖在讀加鎖狀態(tài)時, 所有試圖以讀模式對它進(jìn)行加鎖的線程都可以得到訪問權(quán), 但是如果線程希望以寫模式對此鎖進(jìn)行加鎖, 它必須直到所有的線程釋放鎖. 通常, 當(dāng)讀寫鎖處于讀模式鎖住狀態(tài)時, 如果有另外線程試圖以寫模式加鎖, 讀寫鎖通常會阻塞隨后的讀模式鎖請求, 這樣可以避免讀模式鎖長期占用, 而等待的寫模式鎖請求長期阻塞. 讀寫鎖適合于對數(shù)據(jù)結(jié)構(gòu)的讀次數(shù)比寫次數(shù)多得多的情況. 因為, 讀模式鎖定時可以共享, 以寫模式鎖住時意味著獨占, 所以讀寫鎖又叫共享-獨占鎖.

所謂「讀寫鎖」,就是同時可以被多個讀者擁有,但是只能被一個寫者擁有的鎖。而所謂「多個讀者、單個寫者」,并非指程序中只有一個寫者(線程),而是說不能有多個寫者同時去寫。

下面看一個計數(shù)器的例子。

class Counter { public:Counter() : value_(0) {}// Multiple threads/readers can read the counter's value at the same time.size_t Get() const {boost::shared_lock<boost::shared_mutex> lock(mutex_);return value_;}// Only one thread/writer can increment/write the counter's value.void Increase() {// You can also use lock_guard here.boost::unique_lock<boost::shared_mutex> lock(mutex_);value_++;}// Only one thread/writer can reset/write the counter's value.void Reset() {boost::unique_lock<boost::shared_mutex> lock(mutex_);value_ = 0;}private:mutable boost::shared_mutex mutex_;size_t value_; };

shared_mutex?比一般的?mutex?多了函數(shù)?lock_shared() / unlock_shared()?,允許多個(讀者)線程同時加鎖、解鎖,而?shared_lock?則相當(dāng)于共享版的?lock_guard?。

對?shared_mutex?使用?lock_guard?或?unique_lock?就達(dá)到了寫者獨占的目的。

測試代碼:

boost::mutex g_io_mutex;void Worker(Counter& counter) {for (int i = 0; i < 3; ++i) {counter.Increase();size_t value = counter.Get();boost::lock_guard<boost::mutex> lock(g_io_mutex);std::cout << boost::this_thread::get_id() << ' ' << value << std::endl;} }int main() {Counter counter;boost::thread_group threads;threads.create_thread(boost::bind(Worker, boost::ref(counter)));threads.create_thread(boost::bind(Worker, boost::ref(counter)));threads.join_all();return 0; }

輸出(仍然是隨機性的):

當(dāng)然,對于計數(shù)器來說,原子類型?boost::atomic<>?也許是更好的選擇。

假如一個線程,先作為讀者用?shared_lock?加鎖,讀完后突然又想變成寫者,該怎么辦?

方法一:先解讀者鎖,再加寫者鎖。這種做法的問題是,一解一加之間,其他寫者說不定已經(jīng)介入并修改了數(shù)據(jù),那么當(dāng)前線程作為讀者時所持有的狀態(tài)(比如指針、迭代器)也就不再有效。

方法二:用?upgrade_lock?,它可以當(dāng)做?shared_lock?用,但是必要時可以直接從讀者「升級」為寫者。

{// Acquire shared ownership to read.boost::upgrade_lock<boost::shared_mutex> upgrade_lock(shared_mutex_);// Read...// Upgrade to exclusive ownership to write.boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(upgrade_lock);// Write... }

可惜的是,我沒能給?upgrade_lock?找到一個頗具實際意義的例子。


創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的C++读写锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。