linux 等待进程,Linux 进程等待队列
Linux內核的等待隊列是以雙循環鏈表為基礎數據結構,與進程調度機制緊密結合,能夠用于實現核心的異步事件通知機制。
在這個鏈表中,有兩種數據結構:等待隊列頭(wait_queue_head_t)和等待隊列項(wait_queue_t)。等待隊列頭和等待隊列項中都包含一個list_head類型的域作為"連接件"。它通過一個雙鏈表和把等待tast的頭,和等待的進程列表鏈接起來。從上圖可以清晰看到。所以我們知道,如果要實現一個等待隊列,首先要有兩個部分。隊列頭和隊列項。下面看他們的數據結構。
struct list_head {
struct list_head *next, *prev;
};
struct __wait_queue_head {
spinlock_t lock;
struct list_head task_list;
};
typedef struct __wait_queue_head wait_queue_head_t;
struct __wait_queue {
unsigned int flags;
#define WQ_FLAG_EXCLUSIVE 0x01
void *private;//2.6版本是采用void指針,而以前的版本是struct task_struct * task;
//實際在用的時候,仍然把private賦值為task
wait_queue_func_t func;
struct list_head task_list;
};
所以隊列頭和隊列項是通過list_head聯系到一起的,list_head是一個雙向鏈表,在linux內核中有著廣泛的應用。并且在list.h中對它有著很多的操作。
2.對列頭和隊列項的初始化:
wait_queue_head_t my_queue;
init_waitqueue_head(&my_queue);
直接定義并初始化。init_waitqueue_head()函數會將自旋鎖初始化為未鎖,等待隊列初始化為空的雙向循環鏈表。
DECLARE_WAIT_QUEUE_HEAD(my_queue);
定義并初始化
3.定義等待隊列: DECLARE_WAITQUEUE(name,tsk);
#define DECLARE_WAITQUEUE(name, tsk) /
wait_queue_t name =__WAITQUEUE_INITIALIZER(name, tsk)
#define __WAITQUEUE_INITIALIZER(name, tsk) { task: tsk, task_list: { NULL, NULL }, __WAITQUEUE_DEBUG_INI(name)}
它的解釋是:
通過DECLARE_WAITQUEUE宏將等待隊列項初始化成對應的任務結構,并且用于連接的相關指針均設置為空。其中加入了調試相關代碼。
進程通過執行下面步驟將自己加入到一個等待隊列中:
1) 調用DECLARE_WAITQUEUE()創建一個等待隊列的項;
2) 調用add_wait_queue()把自己加入到等待隊列中。該隊列會在進程等待的條件滿足時喚醒它。在其他地方寫相關代碼,在事件發生時,對等的隊列執行wake_up()操作。
3) 將進程狀態變更為: TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE。
4) 如果狀態被置為TASK_INTERRUPTIBLE ,則信號喚醒進程。即為偽喚醒(喚醒不是因為事件的發生),因此檢查并處理信號。
5) 檢查condition是否為真,為真則沒必要休眠,如果不為真,則調用scheduled()。
6) 當進程被喚醒的時候,它會再次檢查條件是否為真。真就退出循環,否則再次調用scheduled()并一直重復這步操作。
7) condition滿足后,進程將自己設置為TASK_RUNNING 并通過remove_wait_queue()退出。
4.(從等待隊列頭中)添加/移出等待隊列
(1)add_wait_queue()函數: (2)remove_wait_queue()函數:
5.等待事件:(有條件睡眠)
1)wait_event()宏:
#define wait_event(wq, condition) /
do { /
if (condition) /
break; /
__wait_event(wq, condition); /
} while (0)
#define __wait_event_timeout(wq, condition, ret) /
do { /
DEFINE_WAIT(__wait); /
/
for (;;) { /
prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); /
if (condition) /
break; /
ret = schedule_timeout(ret); /
if (!ret) /
break; /
} /
finish_wait(&wq, &__wait); /
} while (0)
在等待會列中睡眠直到condition為真。在等待的期間,進程會被置為TASK_UNINTERRUPTIBLE進入睡眠,直到condition變量變為真。每次進程被喚醒的時候都會檢查condition的值.
(2)wait_event_interruptible()函數:
和wait_event()的區別是調用該宏在等待的過程中當前進程會被設置為TASK_INTERRUPTIBLE狀態.在每次被喚醒的時候,首先檢查condition是否為真,如果為真則返回,否則檢查如果進程是被信號喚醒,會返回-ERESTARTSYS錯誤碼.如果是condition為真,則返回0.
(3)wait_event_timeout()宏:
也與wait_event()類似.不過如果所給的睡眠時間為負數則立即返回.如果在睡眠期間被喚醒,且condition為真則返回剩余的睡眠時間,否則繼續睡眠直到到達或超過給定的睡眠時間,然后返回0.
(4)wait_event_interruptible_timeout()宏:
與wait_event_timeout()類似,不過如果在睡眠期間被信號打斷則返回ERESTARTSYS錯誤碼.
(5) wait_event_interruptible_exclusive()宏
同樣和wait_event_interruptible()一樣,不過該睡眠的進程是一個互斥進程.
6.喚醒隊列:
(1)wake_up()函數:
喚醒等待隊列.可喚醒處于TASK_INTERRUPTIBLE和TASK_UNINTERUPTIBLE狀態的進程,和wait_event/wait_event_timeout成對使用.
2)wake_up_interruptible()函數: #define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
和wake_up()唯一的區別是它只能喚醒TASK_INTERRUPTIBLE狀態的進程.,與wait_event_interruptible/wait_event_interruptible_timeout/ wait_event_interruptible_exclusive成對使用.
TASK_INTERRUPTIBLE,允許通過發送signal喚醒它(即可中斷的睡眠狀態);
TASK_UNINTERRUPTIBLE,不接收任何 singal
7.在等待隊列上睡眠:(無條件睡眠,老內核使用,新內核建議不用)
(1)sleep_on()函數:
該函數的作用是定義一個等待隊列(wait),并將當前進程添加到等待隊列中(wait),然后將當前進程的狀態置為TASK_UNINTERRUPTIBLE,并將等待隊列(wait)添加到等待隊列頭(q)中。之后就被掛起直到資源可以獲取,才被從等待隊列頭(q)中喚醒,從等待隊列頭中移出。在被掛起等待資源期間,該進程不能被信號喚醒。
(2)sleep_on_timeout()函數:
與sleep_on()函數的區別在于調用該函數時,如果在指定的時間內(timeout)沒有獲得等待的資源就會返回。實際上是調用schedule_timeout()函數實現的。值得注意的是如果所給的睡眠時間(timeout)小于0,則不會睡眠。該函數返回的是真正的睡眠時間。
(3)interruptible_sleep_on()函數:
該函數和sleep_on()函數唯一的區別是將當前進程的狀態置為TASK_INTERRUPTINLE,這意味在睡眠如果該進程收到信號則會被喚醒。
(4)interruptible_sleep_on_timeout()函數:
類似于sleep_on_timeout()函數。進程在睡眠中可能在等待的時間沒有到達就被信號打斷而被喚醒,也可能是等待的時間到達而被喚醒。
Linux 進程等待隊列【轉】
本文轉載自:http://blog.csdn.net/dlutbrucezhang/article/details/9212067 Linux內核的等待隊列是以雙循環鏈表為基礎數據結構,與進程調度機制 ...
Linux進程管理知識整理
Linux進程管理知識整理 1.進程有哪些狀態?什么是進程的可中斷等待狀態?進程退出后為什么要等待調度器刪除其task_struct結構?進程的退出狀態有哪些? TASK_RUNNING(可運行狀態) ...
Linux進程的睡眠和喚醒簡析
COPY FROM:http://www.2cto.com/os/201204/127771.html 1 Linux進程的睡眠和喚醒 在Linux中,僅等待CPU時間的進程稱為就緒進程,它們被放置在 ...
linux進程模型總結
Linux進程通過一個task_struct結構體描述,在linux/sched.h中定義,通過理解該結構,可更清楚的理解linux進程模型. ????? 包含進程所有信息的task_struct數據 ...
linux進程解析--進程的創建
通常我們在代碼中調用fork()來創建一個進程或者調用pthread_create()來創建一個線程,創建一個進程需要為其分配內存資源,文件資源,時間片資源等,在這里來描述一下linux進程的創建過程 ...
Linux進程模型
----原文鏈接:http://www.cnblogs.com/biyeymyhjob/archive/2012/08/01/2617884.html------ Linux進程通過一個task_st ...
Linux喚醒搶占----Linux進程的管理與調度(二十三)
1. 喚醒搶占 當在try_to_wake_up/wake_up_process和wake_up_new_task中喚醒進程時, 內核使用全局check_preempt_curr看看是否進程可以搶占當 ...
Linux進程管理 (2)CFS調度器
關鍵詞: 目錄: Linux進程管理 (1)進程的誕生 Linux進程管理 (2)CFS調度器 Linux進程管理 (3)SMP負載均衡 Linux進程管理 (4)HMP調度器 Linux進程管理 ( ...
Linux中等待隊列的實現
1.?????? 等待隊列數據結構 等待隊列由雙向鏈表實現,其元素包括指向進程描述符的指針.每個等待隊列都有一個等待隊列頭(wait queue head),等待隊列頭是一個類型為wait_quequ ...
隨機推薦
asp.net DataSet數據導出到Excel中
方法: [STAThread]///這是必須的??? public override void VerifyRenderingInServerForm(System.Web.UI.Control co ...
ECJTU大一暑假集訓
第二場比賽:一簽到題沒做出來!!!死活不遠做下去了,開始發狂,最后還有2個半小時開始做別的,陸續A了幾道: ?我還能怪誰呢,我渣,我傻逼,就這樣!! 7/19:早就想自己建一個博客了,也就是一直想想沒 ...
Keep two divs sync scroll and example
srcDiv has visible horizontal scrollbar.(style="overflow:auto;") targetDiv has no scrollba ...
Keil C -WARNING L15: MULTIPLE CALL TO SEGMENT
1.第一種錯誤信息 ***WARNING L15: MULTIPLE CALL TO SEGMENT SEGMENT: ?PR?_WRITE_GMVLX1_REG?D_GMVLX1 CALLER1: ...
深入理解C指針之二:C內存管理
原文:深入理解C指針之二:C內存管理 內存管理對所有程序來說都很重要.有時候內存由運行時系統隱式的管理,比如為變量自動分配內存.在這種情況下,變量分配在它所處的函數的棧幀上(每個函數都有它自己的棧幀, ...
Beego學習筆記——Config
配置文件解析 這是一個用來解析文件的庫,它的設計思路來自于database/sql,目前支持解析的文件格式有ini.json.xml.yaml,可以通過如下方式進行安裝: go get github. ...
Java并發基礎:進程和線程之由來
轉載自:http://www.cnblogs.com/dolphin0520/p/3910667.html 在前面,已經介紹了Java的基礎知識,現在我們來討論一點稍微難一點的問題:Java并發編程. ...
如何快速清理 docker 資源
如果經常使用 docker,你會發現 docker 占用的資源膨脹很快,其中最明顯也最容易被察覺的應該是對磁盤空間的占用.本文將介紹如何快速的清理 docker 占用的系統資源,具體點說就是刪除那些無 ...
關于URL隱藏index.php方法
在phpstudy上修改了php版本5.6以上后,tp5框架原URL重寫模式發生變化.需要在public目錄下的.htaccess作出如圖修改,原理未知.
Intellij IDEA 代碼格式化/保存時自動格式化
這里介紹使用google style 一.安裝插件 1.settings -> plugins 選擇?Browse repositories… 2.搜索google-java-format 和 ...
總結
以上是生活随笔為你收集整理的linux 等待进程,Linux 进程等待队列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 职高学计算机走单招是,职高学生不用愁了,
- 下一篇: oracle 11gr2 asm安装,O