一坚洽、概述
等待隊(duì)列在內(nèi)核中有很多用途,尤其在中斷處理笛质、進(jìn)程同步及定時泉沾。等待隊(duì)列實(shí)現(xiàn)事件上的條件等待;希望等待特定事件的進(jìn)程把自己放在合適的等待隊(duì)列妇押,并放棄控制權(quán)跷究。
二、相關(guān)結(jié)構(gòu)體
等待隊(duì)列由雙向鏈表實(shí)現(xiàn)敲霍,其元素包括指向進(jìn)程描述符的指針俊马。每個等待隊(duì)列都有一個等待隊(duì)列頭,即wait_queue_head_t結(jié)構(gòu)肩杈。
struct __wait_queue_head {
spinlock_t lock;
struct list_head task_list; //等待進(jìn)程鏈表
};
typedef struct __wait_queue_head wait_queue_head_t;等待隊(duì)列鏈表中的元素柴我,即wait_queue_t結(jié)構(gòu)
等待隊(duì)列鏈表中的每個元素代表一個睡眠進(jìn)程,進(jìn)程描述符地址存入private字段中扩然。
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
struct __wait_queue {
unsigned int flags; //標(biāo)志
define WQ_FLAG_EXCLUSIVE 0x01
void *private; //進(jìn)程描述符
wait_queue_func_t func; //喚醒函數(shù)艘儒,缺省為default_wake_function
struct list_head task_list; //鏈接到等待隊(duì)列鏈表中
};
typedef struct __wait_queue wait_queue_t;
A、定義和初始化等待隊(duì)列頭
DECLARE_WAIT_QUEUE_HEAD(wait);//初始化一個等待隊(duì)列頭 wait
或者動態(tài)地, 如下:
wait_queue_head_t wait;
init_waitqueue_head(&wait);
B夫偶、休眠進(jìn)程
wait_event(wait, condition) //將當(dāng)前進(jìn)程的狀態(tài)設(shè)置為 TASK_UNINTERRUPTIBLE
wait_event_interruptible(wait, condition) //TASK_INTERRUPTIBLE
wait_event_timeout(wait, condition, timeout) //TASK_UNINTERRUPTIBLE
wait_event_interruptible_timeout(wait, condition, timeout) //TASK_INTERRUPTIBLE
備注:
wait 是等待隊(duì)列頭界睁, condition 是條件,如果調(diào)用 wait_event 前 condition == 0 兵拢,則調(diào)用 wait_event 之后翻斟,當(dāng)前
進(jìn)程就會休眠。
TASK_INTERRUPTIBLE 與 TASK_UNINTERRUPTIBLE 區(qū)別在于说铃,它的休眠是否會被信號打斷访惜,別的進(jìn)程發(fā)來一個信號比如 kill 嘹履,
TASK_INTERRUPTIBLE 就會醒來去處理。然而 TASK_UNINTERRUPTIBLE 不會疾牲。schedule()植捎,進(jìn)程調(diào)度,而 schedule_timeout()
進(jìn)行調(diào)度之后阳柔,一定時間后自動喚醒焰枢。
C、喚醒進(jìn)程
void wake_up(wait_queue_head_t *wait);
void wake_up_interruptible(wait_queue_head_t *wait);
備注:
對應(yīng)于不同的進(jìn)程狀態(tài)舌剂,使用不同的喚醒函數(shù)济锄。比如你調(diào)用 wake_up 去喚醒一個使用 wait_event 等,進(jìn)入休眠的進(jìn)程霍转,喚醒
之后荐绝,它會判斷 condition 是否為真,如果還是假的繼續(xù)睡眠避消。