天天看點

讀寫信号量(todo)

讀寫信号量的相關API有:

DECLARE_RWSEM(name)

該宏聲明一個讀寫信号量name并對其進行初始化。

void init_rwsem(struct rw_semaphore *sem);

該函數對讀寫信号量sem進行初始化。

void down_read(struct rw_semaphore *sem);

讀者調用該函數來得到讀寫信号量sem。該函數會導緻調用者睡眠,是以隻能在程序上下文使用。

int down_read_trylock(struct rw_semaphore *sem);

該函數類似于down_read,隻是它不會導緻調用者睡眠。它盡力得到讀寫信号量sem,如果能夠立即得到,它就得到該讀寫信号量,并且傳回1,否則表示不能立刻得到該信号量,傳回0。是以,它也可以在中斷上下文使用。

void down_write(struct rw_semaphore *sem);

寫者使用該函數來得到讀寫信号量sem,它也會導緻調用者睡眠,是以隻能在程序上下文使用。

int down_write_trylock(struct rw_semaphore *sem);

該函數類似于down_write,隻是它不會導緻調用者睡眠。該函數盡力得到讀寫信号量,如果能夠立刻獲得,就獲得該讀寫信号量并且傳回1,否則表示無法立刻獲得,傳回0。它可以在中斷上下文使用。

void up_read(struct rw_semaphore *sem);

讀者使用該函數釋放讀寫信号量sem。它與down_read或down_read_trylock配對使用。如果down_read_trylock傳回0,不需要調用up_read來釋放讀寫信号量,因為根本就沒有獲得信号量。

void up_write(struct rw_semaphore *sem);

寫者調用該函數釋放信号量sem。它與down_write或down_write_trylock配對使用。如果down_write_trylock傳回0,不需要調用up_write,因為傳回0表示沒有獲得該讀寫信号量。

<a>void downgrade_write(struct rw_semaphore *sem);</a>

該函數用于把寫者降級為讀者,這有時是必要的。因為寫者是排他性的,是以在寫者保持讀寫信号量期間,任何讀者或寫者都将無法通路該讀寫信号量保護的共享資源,對于那些目前條件下不需要寫通路的寫者,降級為讀者将,使得等待通路的讀者能夠立刻通路,進而增加了并發性,提高了效率。

讀寫信号量适于在讀多寫少的情況下使用,在linux核心中對程序的記憶體映像描述結構的通路就使用了讀寫信号量進行保護。

究竟什麼時候使用自旋鎖什麼時候使用信号量,下面給出建議的方案

當對低開銷、短期、中斷上下文加鎖,優先考慮自旋鎖;當對長期、持有鎖需要休眠的任務,優先考慮信号量。

繼續閱讀