Linux同步 讀寫訊號量

2021-07-03 15:06:09 字數 3592 閱讀 5200

以下內容**: 訊號量

一,訊號量和自旋鎖的區別

訊號量與自旋鎖有一定的區別,訊號量在無法得到資源時,核心執行緒處於睡眠阻塞狀態,而自旋鎖處於忙等待狀態。因此,如果資源被占用時間很短時,使用自旋鎖較好,因為它可節約排程時間。如果資源被占用的時間較長,使用訊號量較好。

二,訊號量相關的api

訊號量的相關api

函式定義

功能說明

sema_init(struct semaphore *sem, int val)

初始化訊號量,將訊號量計數器值設定val。

down(struct semaphore *sem)

獲取訊號量,不建議使用此函式。

down_interruptible(struct semaphore *sem)

可被中斷地獲取訊號量,如果睡眠被訊號中斷,返回錯誤-eintr。

down_killable (struct semaphore *sem)

可被殺死地獲取訊號量。如果睡眠被致命訊號中斷,返回錯誤-eintr。

down_trylock(struct semaphore *sem)

嘗試原子地獲取訊號量,如果成功獲取,返回0,不能獲取,返回1。

down_timeout(struct semaphore *sem, long jiffies)

在指定的時間jiffies內獲取訊號量,若超時未獲取,返回錯誤-etime。

up(struct semaphore *sem)

釋放訊號量sem。

讀寫訊號量的相關api

api函式定義

功能說明

declare_rwsem(name)

宣告名為name的讀寫訊號量,並初始化它。

void init_rwsem(struct rw_semaphore *sem);

對讀寫訊號量sem進行初始化。

void down_read(struct rw_semaphore *sem);

讀者用來獲取sem,若沒獲得時,則呼叫者睡眠等待。

void up_read(struct rw_semaphore *sem);

讀者釋放sem。

int down_read_trylock(struct rw_semaphore *sem); 讀者嘗試獲取sem,如果獲得返回1,如果沒有獲得返回0。可在中斷上下文使用。

void down_write(struct rw_semaphore *sem);

寫者用來獲取sem,若沒獲得時,則呼叫者睡眠等待。

int down_write_trylock(struct rw_semaphore *sem);

寫者嘗試獲取sem,如果獲得返回1,如果沒有獲得返回0。可在中斷上下文使用

void up_write(struct rw_semaphore *sem);

寫者釋放sem。

void downgrade_write(struct rw_semaphore *sem);

把寫者降級為讀者。

三,訊號量相關的函式

訊號量的結構體:

struct semaphore ;

讀寫訊號量的結構, 在include/linux/rwsem-spinlock.h中

struct rw_semaphore ;

讀者加鎖

讀者加鎖是通過down_read()函式完成的,

void __sched __down_read(struct rw_semaphore *sem)

/*執行到這裡,說明不能獲取sem,將當前程序加入等待佇列進行等待*/

tsk = current;

set_task_state(tsk, task_uninterruptible);

/* 建立等待佇列成員*/

waiter.task = tsk;

waiter.flags = rwsem_waiting_for_read; /*表示等待讀操作*/

get_task_struct(tsk); /*程序使用計數加1*/

list_add_tail(&waiter.list, &sem->wait_list); /*將等待成員加到等待佇列尾*/

/* 不再需要訪問等待佇列,因此,這裡解鎖*/

spin_unlock_irq(&sem->wait_lock);

/* 讀者等待獲取sem */

for (;;)

/*執行這裡,退出等待,說明可以獲取sem了*/

tsk->state = task_running;

out:

;}

讀者解鎖

void __up_read(struct rw_semaphore *sem)

/*喚醒乙個寫者*/

static inline struct rw_semaphore *__rwsem_wake_one_writer(struct rw_semaphore *sem)

寫者加鎖

void __sched down_write(struct rw_semaphore *sem)

void __sched __down_write(struct rw_semaphore *sem)

函式__down_write_nested完成加寫者鎖的具體操作。當沒有讀者或寫者操作時,寫者才可以獲取寫者鎖。寫者鎖是獨佔的。如果有其他寫者或讀者操作時,寫者必須等待。其列出如下:

void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)

/*執行到這裡,說明有讀者或寫者在操作,需要等待*/

tsk = current;

set_task_state(tsk, task_uninterruptible);

/* 建立等待佇列成員*/

waiter.task = tsk;

waiter.flags = rwsem_waiting_for_write; /*標識為等待寫操作*/

get_task_struct(tsk); /*程序上下文使用計數加1*/

list_add_tail(&waiter.list, &sem->wait_list); /*加到等待佇列尾*/

spin_unlock_irq(&sem->wait_lock);

/* 進行等待*/

for (;;)

/*被喚醒*/

tsk->state = task_running;

out:

;}

解寫者鎖

函式up_write釋放寫者鎖,將讀者計數設定為0,其列出如下:

void up_write(struct rw_semaphore *sem)

void __up_write(struct rw_semaphore *sem)

讀寫訊號量(todo)

讀寫訊號量的相關api有 declare rwsem name 該巨集宣告乙個讀寫訊號量name並對其進行初始化。void init rwsem struct rw semaphore sem 該函式對讀寫訊號量sem進行初始化。void down read struct rw semaphore ...

核心同步方法之讀寫訊號量

讀寫訊號量在核心中是由rw semaphore結構表示的 在中 the semaphore definition struct rw semaphore 靜態建立讀寫訊號量 define rwsem initializer name define declare rwsem name struct ...

linux訊號量實現執行緒讀寫同步

本次使用linux訊號量來實現執行緒讀寫同步,還是實現之前寫的那個讀和寫陣列的例子,本次在寫的過程中出現乙個死鎖問題,原因是先進入臨界區,然後等待訊號量,這樣造成讀函式在等待訊號量,寫函式在等待進入臨界區,所以修改了下程式,先進入訊號量的等待,再進入臨界區的等待,這也說明了我們寫程式時不能長時間占用...