boost 是否像 Linux 一樣提供讀寫自旋鎖機制?

如題,我知道boost已經提供讀寫鎖功能,但獲取不到鎖的時候似乎採取的是阻塞操作,這會發生線程上下文切換和較大的性能損失。不知道當前boost是否提供讀寫自旋鎖功能,實現多讀一寫,獲取不到鎖時不阻塞?


用戶態 spinlock 這個東西,其實沒多大用。(其實在內核態用的地方也很少,基本上依賴 scheduler 的代碼都不能用。)

如果你看過 Linux kernel 代碼,你會知道在 disable SMP 的時候,spinlock 是一個空函數。在 Linux kernel 里,spinlock 僅僅是一個在多核之間做同步的機制。這個機制用在普通的線程模型上意義不大。

為什麼說意義不大呢?你看用 spinlock 的初衷是什麼?是為了讓 waiting thread 不被掛起,不用產生進程 suspend-reschedule 的開銷。但是你要讓 waiting thread 等待的盡量短,還要有一個要求,就是 lock-owning thread 得趕緊把事情幹完。那你怎麼保證 lock-owning thread 趕緊完事呢?你得保證 waiting thread 和 lock-owner 運行在不同 CPU 上,而且 lock-owner 最好能 disable interrupt 防止自己被 preemptively suspend。否則的話,不光還要有 thread switch,而且 lock-owner 還可能去空等待 waiting thread,因為後者在 busy-waiting 而並非掛起。所以你看,這個條件只有在 kernel 里操作多核的特殊代碼才能滿足。在用戶空間的線程是不知道自己是不是運行在同一個核上的。

所以說 spinlock 在用戶空間有可能反而比 mutex 要慢。這個東西實在是雞肋。只要你已經把自己的代碼託付給了 scheduler,mutex 是目前最好的同步模型。(當然 atomic 和 memory barrier 也是,但是它們都不能構建任意長的 critical region。)

而且 disk I/O 本來就會 voluntarily relinquish CPU。這種 lock-owner 為什麼還要用 spin lock 我就看不懂了。


自旋鎖是用於多核之間互斥。場景應該是拿鎖迅速,占鎖時間短,迅速釋放,主要是關中斷關調度。為什麼要自旋呢,因為自旋花費的時間代價小於上下文切換的代價。如果不是這種場景就不要用。用戶態程序不需要自旋鎖,如果死在臨界區,鎖釋放不了,調度中斷被關,系統就掛了。


在用戶態編程里,spinlock確實是很雞肋,甚至不如雞肋,能不用盡量不用。

其實在linux里,mutex的實現,在等待鎖的時候,會根據情況自動自璇一小段時間的。

而在用戶態自己使用spinlock的效果往往比直接mutex要更差。


Slim Reader/Writer (SRW) Locks (Windows)

如果你是想在Windows上用,但是又不放心的話,可以直接用這個,是自旋的。


Usage examples

你為什麼不用搜索引擎?

你為什麼不用搜索引擎?

你為什麼不用搜索引擎?


boost/smart_ptr/detail/spinlock.hpp ,這個就是boost庫下的spinlock,直接include就可以使用了。但是讀寫鎖需要自己實現,facebook folly庫中有一個讀寫鎖的設計。


在atomic包里不是有個spinlock么?


使用std的atomic_flag可以模擬出自旋鎖,基於它也可以自己封裝一個spin_lock類


推薦閱讀:

多線程讀內存變慢如何解決?
為什麼在同一進程中創建不同線程,但線程各自的變數無法在線程間互相訪問?
下面代碼是線程不安全的代碼,請問為什麼很難跑出不安全的樣例?
Linux的epoll使用LT+非阻塞IO和ET+非阻塞IO有效率上的區別嗎?

TAG:CC | 多線程 | BoostC庫 |