天天看點

Q42:互斥鎖與讀寫鎖

互斥鎖與讀寫鎖

互斥鎖: mutex,用于保證在任何時刻,都隻能有一個線程通路該對象。當擷取鎖操作失敗時,線程會進入睡眠,等待鎖釋放時被喚醒。

讀寫鎖: rwlock,分為讀鎖和寫鎖。

處于讀操作時,可以允許多個線程同時獲得讀操作。但是同一時刻隻能有一個線程可以獲得寫鎖。其它擷取寫鎖失敗的線程都會進入睡眠狀态,直到寫鎖釋放時被喚醒。

注意:寫鎖會阻塞其它讀寫鎖。當有一個線程獲得寫鎖在寫時,讀鎖也不能被其它線程擷取;寫者優先于讀者(一旦有寫者,則後續讀者必須等待,喚醒時優先考慮寫者)。适用于讀取資料的頻率遠遠大于寫資料的頻率的場合。

互斥鎖和讀寫鎖的差別:

(1)讀寫鎖區分讀者和寫者,而互斥鎖不區分。

(2)互斥鎖同一時間隻允許一個線程通路該對象,無論讀寫;讀寫鎖同一時間内隻允許一個寫者,但是允許多個讀者同時讀對象。

Linux的4種鎖機制:

  • 互斥鎖:mutex,用于保證在任何時刻,都隻能有一個線程通路該對象。當擷取鎖操作失敗時,線程會進入睡眠,等待鎖釋放時被喚醒。
  • 讀寫鎖:rwlock,分為讀鎖和寫鎖。處于讀操作時,可以允許多個線程同時獲得讀操作。但是同一時刻隻能有一個線程可以獲得寫鎖。其它擷取寫鎖失敗的線程都會進入睡眠狀态,直到寫鎖釋放時被喚醒。 注意:寫鎖會阻塞其它讀寫鎖。當有一個線程獲得寫鎖在寫時,讀鎖也不能被其它線程擷取;寫者優先于讀者(一旦有寫者,則後續讀者必須等待,喚醒時優先考慮寫者)。适用于讀取資料的頻率遠遠大于寫資料的頻率的場合。
  • 自旋鎖:spinlock,在任何時刻同樣隻能有一個線程通路對象。但是當擷取鎖操作失敗時,不會進入睡眠,而是會在原地自旋,直到鎖被釋放。這樣節省了線程從睡眠狀态到被喚醒期間的消耗,在加鎖時間短暫的環境下會極大的提高效率。但如果加鎖時間過長,則會非常浪費CPU資源。
  • RCU:即read-copy-update,在修改資料時,首先需要讀取資料,然後生成一個副本,對副本進行修改。修改完成後,再将老資料update成新的資料。使用RCU時,讀者幾乎不需要同步開銷,既不需要獲得鎖,也不使用原子指令,不會導緻鎖競争,是以就不用考慮死鎖問題了。而對于寫者的同步開銷較大,它需要複制被修改的資料,還必須使用鎖機制同步并行其它寫者的修改操作。在有大量讀操作,少量寫操作的情況下效率非常高。

繼續閱讀