核心中的休眠是通過等待佇列來處理的。等待佇列是乙個由正在等待某個事件發生的程序組成的乙個簡單鍊錶。在核心用wait_queue_head_t來表示。
定義:declare_waitqueue()(靜態定義)
或init_waitqueue_head()(動態定義)
在核心中實現休眠的方法有點複雜,實現的模板如下:/*『
q』isthe
wait
queue
wewish
tosleep
on*/
define_wait(wait);
add_wait_queue(q,
&wait);
//這個函式呼叫是可選
while
(!condition)
finish_wait(&q,
&wait);
乙個程序執行如下步驟將自己加入到乙個等待佇列中:
乙個例子:
staticssize_t inotify_read(struct file *file, char __user *buf,
size_t count, loff_t *pos)
ret= -eagain;
if(file->f_flags & o_nonblock)
break;
ret= -eintr;
if(signal_pending(current))
break;
if(start != buf)
break;
schedule();}
finish_wait(&group->notification_waitq,
&wait);
if(start != buf && ret != -efault)
ret= buf - start;
returnret; }
另一種模板:
/*helper thread */
staticint
my_thread(void*unused)
/*do the real work */
/*... */ }
/*bail out of the wait queue */
__set_current_state(task_running);
remove_wait_queue(&my_thread_wait,
&wait);
/*atomically signal completion and exit */
complete_and_exit(&my_thread_exit,0); }
喚醒
通過函式wake_up()喚醒,它將喚醒所有在特定等待佇列上等待的程序。一般情況下預設的喚醒函式為:default_wake_function()。它會呼叫try_to_wake_up(),將被喚醒的程序狀態設定為task_running,然後呼叫enqueue_task()將該程序加入到紅黑樹中,如果被喚醒的程序的優先順序大於當前程序的優先順序,設定need_resched為1。休眠與喚醒之間的關係如下:
偽喚醒是指程序是因為接收到某個訊號而被喚醒,而不是等待事件發生而導致其被喚醒。
在最新的核心**中,一般會使用更高層的介面:wait_event
或wait_event_timeout介面。使用wake_up_all
喚醒所有新增到某個等待佇列鍊錶中的等待佇列。使用模板如下:
1. 初始化乙個等待佇列頭:
init_waitqueue_head(&ret->wait_queue);
注: 判斷佇列是否為空: waitqueue_active(...), 返回
false
即表示隊列為空
. 2. 等待某個條件發生:
wait_event(...) 或
wait_event_timeout(...)
3. 喚醒佇列
wake_up_all(...)
執行緒等待與喚醒
標籤 多執行緒 所有的等待和喚醒執行緒,都是針對某個具體物件例項的.api介面 說明wait 讓當前執行緒進入等待 阻塞 狀態,直到其他執行緒呼叫此物件的notify 或notifyall 來喚醒,之後該執行緒進入就緒狀態.wait long timeout 讓當前執行緒進入阻塞狀態,直到其他執行緒...
等待與喚醒機制
1 執行緒間通訊 概念 多執行緒在處理同乙個資源,但是處理的動作卻不相同。為什麼處理執行緒間通訊?多執行緒併發執行時,在預設情況下cpu是隨機切換執行緒的,當我們需要多執行緒來共同完成一件任務,並且我們希望他們有規律的執行,那麼多執行緒之間需要一些協調通訊,以此來幫我們達到多執行緒共同操作乙份資料。...
linux程序的休眠(等待佇列)
size medium 當程序以阻塞的方式通訊,在得到結果前程序會掛起休眠。為了將程序以一種安全的方式進入休眠,我們需要牢記兩條規則 一 永遠不要在原子上下文中進入休眠。二 程序休眠後,對環境一無所知。喚醒後,必須再次檢查以確保我們等待的條件真正為真 簡單休眠 完成喚醒任務的 還必須能夠找到我們的程...