最近一套方案涉及到內核線程之間的同步,用到了函數wait_event_interruptible_timeout函數,大致是這樣:
A:是一個后台的線程,平常沒事就睡覺,有時被喚醒,或者每5分鍾醒一次看看;
B:普通線程,負責喚醒后台的線程讓它干活!
此處喚醒的操作使用到的函數是wake_up,然后進程A使用wait_event_interruptible_timeout讓自己睡覺。下面詳細分析其中的機制:
wait_event_interruptible_timeout: sleep util a condition get true or a timeout elapses
記得以前看侯捷老師那本MFC架構分析時,最吸引人的概念是事件觸發模型,事件觸發模型很好理解,但是AA事件發生了,那么BB事件就應該發生,在我們這個例子里就是B普通線程發生了,那么就讓A發生!
具體是怎么實現的?
1)wait_event_interruptible_timeout是把調用這個函數的進程鏈入到一個list中,並且
最重要的結構體是wait_queue_head_t,這個結構體包含兩個成員變量:spin_lock lock 和 struct list_head task_list
可知這個結構體的目的其實也是比較簡單的:就是把一個進程插入到一個隊列中去!
函數層層遞進,其實調用的是 wait_event 函數,這個函數其實就是一個死循環:
schedule_timeout是什么意思。不斷地把函數添加到wait_queue_head_t->task_list中去,然后調用schedule_timeout調度,這個schedule_timeout是什么意思?就是不斷地調度出去,但是這個線程目前在兩個地方存在,一個是內核的調度隊列,一個是等待隊列的鏈表中。那么問題來了,在這里一般問題是說[可中斷的等待,不可中斷的等待]有什么區別?
在非可中斷的情況下,是怎么實現的事件觸發,其實也是不斷地去檢查condition是否成立,那么這個檢查的時間粒度肯定是比較低的。到底是多少?
在timeout之間的位置,怎么識別事件是否到來!
uninterruptible狀態是指:uninterruptible的線程只能通過wake_up的方式【uninterruptible也是在schedule的視野范圍之內!只是調度其肯定不會選你就對了】
調度器