天天看點

Linux核心34-讀/寫信号量1 讀/寫信号量的工作原理2 讀/寫信号量的資料結構3 讀/寫信号量的有關API

每一種技術的出現必然是因為某種需求。正因為人的本性是貪婪的,是以科技的創新才能日新月異。

1 讀/寫信号量的工作原理

讀/寫信号量和讀/寫自旋鎖類似,不同的地方是程序在等待讀/寫信号量的時候處于挂起狀态,而在等待讀/寫自旋鎖的時候是處于忙等待,也就是自旋的狀态中。

那也就是說,讀/寫信号量同讀/寫自旋鎖一樣,對于讀操作,多個核心控制路徑可以并發請求一個讀寫信号量;而對于寫操作,每個核心控制路徑必須獨占通路受保護的資源。是以,對于讀/寫信号量來說,寫操作的時候,既不可以進行讀操作,也不可以進行寫操作。讀/寫信号量提高了核心中的并發數量,也同時提高了系統的整體性能。

核心嚴格按照先進先出(FIFO)的原則處理等待讀/寫信号量的程序。讀程序或者寫程序一旦請求信号量失敗,就被寫到信号量等待隊列的隊尾。當信号量被釋放後,隊列中的第一個程序先被執行,因為它先被喚醒。如果喚醒的是一個寫程序,那麼隊列中其它程序繼續休眠。如果喚醒的是一個讀程序,寫程序之前的所有讀程序都會被喚醒獲得信号量;但是寫程序之後的讀程序繼續休眠。

2 讀/寫信号量的資料結構

讀/寫信号量使用資料結構

rw_semaphore

表示,其成員為:

  • count

    一個32位的整形數,被分割成兩個16位的計數器。高16位的計數器以2的補碼形式表示非等待寫程序和等待核心控制路徑的數量,低16位表示非等待讀程序和非等待寫程序的總數。

  • wait_list

    等待程序的清單。每個元素是一個

    rwsem_waiter

    資料結構,包含指向休眠程序描述符的指針和一個标志,這個标志表明程序申請信号量是要讀取還是寫入。
  • wait_lock

    自旋鎖,用來保護等待隊列和

    rw_semaphore

    資料結構。

3 讀/寫信号量的有關API

初始化函數為

init_rwsem()

,用其可以初始化一個

rw_semaphore

資料結構,将count設為0,wait_lock自旋鎖設為未使用,wait_list設為空清單。

down_read()

down_write()

函數分别用來請求讀信号量和寫信号量。同理,

up_read()

up_write()

函數分别用來釋放讀信号量和寫信号量。

down_read_trylock()

down_write_trylock()

函數分别與

down_read()

down_write()

函數類似,隻是當信号量忙的時候不會阻塞程序。最後,還有一個重要的函數,

downgrade_write()

,用于寫程序使用完寫信号量之後,自動将其轉換成一個讀信号量。這些函數的實作與普通信号量的實作極其類似,是以,在此,我們就不再較長的描述其實作過程了。