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