當進程等待資源或者事件時,就進入睡眠狀態。有兩種睡眠態,不可中斷睡眠態(TASK_UNINTERRUPTIBLE)和可中斷睡眠態(TASK_INTERRUPTIBLE)。處于可中斷睡眠態的進程不光可以由wake_up直接喚醒,還可以由信號喚醒。在schedule()函數中,會把處于可中斷睡眠態并且收到信號的進程變成運行態,使他參與調度選擇。Linux0.11中進入可中斷睡眠狀態的方法有3中調用i" />

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Linux0.11內核--進程的調度(運行態(就緒態)和睡

系統 4924 0

<!-- p { margin-bottom: 0.08in; } -->

當進程等待資源或者事件時,就進入睡眠狀態。有兩種睡眠態,不可中斷睡眠態( TASK_UNINTERRUPTIBLE )和可中斷睡眠態( TASK_INTERRUPTIBLE )。

處于可中斷睡眠態的進程不光可以由 wake_up 直接喚醒,還可以由信號喚醒。在 schedule() 函數中,會把處于可中斷睡眠態并且收到信號的進程變成運行態,使他參與調度選擇。 Linux0.11 中進入可中斷睡眠狀態的方法有 3

  1. 調用 interruptible_sleep_on() 函數

  2. 調用 sys_pause() 函數

  3. 調用 sys_waitpid() 函數。

第一種情況用于等待外設資源時(如等待 I/O 設備),這時當前進程會掛在對應的等待隊列上。第二第三種情況用于事件,即等待信號。

進程要進入不可中斷睡眠態,只能通過 sleep_on() 函數。要使處于不可中斷睡眠態的進程進入運行態,只能由其他進程調用 wake_up() 將它喚醒。當進程等待系統資源(比如高速緩沖塊,文件 i 節點或者文件系統的超級塊)時,會調用 sleep_on() 函數,使當前進程掛起在相關資源的等待隊列上。

這部分代碼很短,一共三個函數 sleep_on() , wake_up() interruptible_sleep_on() 。在 sched.c 中。但是代碼比較難理解,因為構造的等待隊列是一個隱式隊列,利用進程地址空間的獨立性隱式地連接成一個隊列。這個想法很奇妙。

<!-- p { margin-bottom: 0.08in; } -->

sleep_on()

<!-- p { margin-bottom: 0.08in; } -->

這個函數牽涉到 3 個指針, p , tmp current 。

p 是指向指針的指針,實際上 *p 指向的是等待隊列頭。系統資源(高速緩沖塊,文件 i 節點或者文件系統的超級塊)的數據結構中都一個 struct task_struct * 類型的指針,指向的就是等待該資源的進程隊列頭。比如 i 節點中的 i_wait ,高速緩沖塊中的 b_wait ,超級塊中的 s_wait *p 對于等待隊列上的所有進程都是一樣的。

current 指向的是當前進程指針,是全局變量。

tmp 位于當前進程的地址空間內,是局部變量。不同的進程有不同 tmp 變量。等待隊列就是利用這個變量把所有等待同一個資源的進程連接起來。具體的說,所有等待在隊列上的進程,都是在 sleep_on() schedule() 中被切換出去的,這些進程還停留在 sleep_on() 函數中,在函數的堆棧空間里面,存放了局部變量 tmp

假如當前進程要進入某個高速緩沖塊的等待隊列,而且該等待隊列上已經有另外兩個進程 task1 task2 先后進入。形成的隊列如圖。等待隊列是堆棧式的,先進入隊列的進程排在最后。

Linux0.11內核--進程的調度(運行態(就緒態)和睡眠態之間的轉換)

<!-- p { margin-bottom: 0.08in; } -->

在調用了 sleep_on() 的地方,我們可以發現 sleep_on() 往往是放在一個循環中的(比如 wait_on_buffer() , wait_on_inode() lock_inode() , lock_super() , wait_on_super() 等函數)。當進程從 sleep_on() 返回時,并不能保證當前進程取得了資源使用權,因為調用 wake_up() 進程切換到從 sleep_on() 中蘇醒的過程中,發生了進程調度,中間很可能有別的進程取得了資源。

wake_up()

<!-- p { margin-bottom: 0.08in; } --> <!-- p { margin-bottom: 0.08in; } -->

下面分析 sleep_on() wait_up() 配合使用的情況

情況一 游離隊列的產生

先分析一下 sleep_on() wake_up() 在通常情況下的工作原理??紤]一個非常簡單的情況,假設目前系統只有 3 個進程,且都等在隊列上,隊列的頭指針設為 wait

<!-- p { margin-bottom: 0.08in; } -->

然后系統資源得到釋放,當前進程調用 wake_up(wait) 。這時 Task C 變成了運行態。

<!-- p { margin-bottom: 0.08in; } -->

之后進程調度發生, Task C 被選中,開始運行。 Task C 是從 sheep_on() 中的 schedule() 的后一條語句開始運行,它把 Task B 的狀態變成運行態。隨后 Task C 退出 sheep_on() 函數,堆棧中的局部變量 tmp 消失,這樣再沒有指向 Task B 的指針, Task B 開頭的隊列游離了。

Linux0.11內核--進程的調度(運行態(就緒態)和睡眠態之間的轉換)

<!-- p { margin-bottom: 0.08in; } -->

情況 1-1

這時對同一個資源有兩個進程是可運行狀態,但是當前進程是 Task C ,只要它不調用 schedule ,它是不會被搶斷的。因此 Task C 繼續運行,取得了它想要的資源,這時 Task C 可以完成它的任務了。當進程調度再次發生時, Task B 會被選中,同樣, Task B 會把 Task A 變成可運行態,而它自己得到了資源。最終 Task A 也會得到執行。這樣,等待在一個資源上的三個任務最終都得到運行。

情況 1-2

假設 Task C 在得到資源后,又主動調用了 schedule() ,進程調度程序這時選中了 Task B 。 Task B 從上次中斷的地方開始運行,即從 sleep_on() schedule() 后面的語句開始運行。它會把 Task A 也變成可運行狀態。然后退出 sleep_on() , tmp 變量消失。但是不幸的是它發現資源仍然被占用,所以再次進入睡眠,又連接到 wait 隊列上了。

Linux0.11內核--進程的調度(運行態(就緒態)和睡眠態之間的轉換)

<!-- p { margin-bottom: 0.08in; } -->

從這個情況可以看到,雖然系統運行過程中,可能會把等待隊列切分成很多游離隊列,但是這些隊列頭上的進程都是運行態,這保證 schedule() 函數最終還是會找到它。

情況二 游離隊列的合并

假設目前進程等待資源的情況如下,某個進程占用資源不放,導致有 7 個進程等待該資源。產生 3 個隊列,其中兩個游離。

Linux0.11內核--進程的調度(運行態(就緒態)和睡眠態之間的轉換)

<!-- p { margin-bottom: 0.08in; } -->

這時調度函數選中 Task E 執行, Task E 先喚醒 Task D 但發現資源不能用,再次睡眠,把自己移到 wait 隊列,脫離了游離隊列。調度再次發生。

Linux0.11內核--進程的調度(運行態(就緒態)和睡眠態之間的轉換)

<!-- p { margin-bottom: 0.08in; } -->

假如這時 Task B 得到運行,同樣 Task B 也只能喚醒 Task A ,而把自己移動到等待隊列

Linux0.11內核--進程的調度(運行態(就緒態)和睡眠態之間的轉換)

p { margin-bottom: 0.08in; }

這樣,只要游離隊列頭上的進程是運行態,游離隊列可以再次合并到原先的等待隊列上。

p { margin-bottom: 0.08in; }

interruptible_sleep_on()

Linux0.11內核--進程的調度(運行態(就緒態)和睡眠態之間的轉換)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲国产精品欧美综合 | 综合另类小说色区色噜噜 | 特级毛片在线 | 国产综合成人久久大片91 | 99爱在线精品视频网站 | 天天干天天曰 | 精品亚洲综合在线第一区 | 97在线观看免费观看高清 | 日日操综合| 69日本人xxxx16—18 | 夜夜操网站 | 91久久澡人人爽人人添 | 久久综合久久精品 | 国产精品久久久久久一级毛片 | 午夜精品久久久久久久99热浪潮 | 国产精品高清免费网站 | 99精品国产福利在线观看 | 91精品全国免费观看青青 | 日本二区在线观看 | 久久天堂夜夜一本婷婷麻豆 | 色久综合 | 欧美一区二区三 | 99热福利| 久久er国产精品免费观看2 | 成人免费牛牛在线视频 | 一级做a爱片特黄在线观看免费看 | 久久国产亚洲欧美日韩精品 | 超清波多野结衣精品一区 | 狠狠操狠狠操狠狠操 | 麻豆久久婷婷国产综合五月 | 伊人色综合一区二区三区 | 高清国产天干天干天干不卡顿 | 久草在线视频精品 | 羞羞视频在线免费 | 久久香蕉国产精品一区二区三 | 日韩欧美亚洲综合久久影院d3 | 国产成年女一区二区三区 | 久久99国产一区二区三区 | 特级黄色毛片 | 日本免费人成黄页网观看视频 | 俄罗斯美女逼 |