Linux 進(jìn)程調(diào)度全知道

Linux 進(jìn)程調(diào)度器是一個(gè)進(jìn)程嗎? 還是一個(gè)策略

Linux 進(jìn)程調(diào)度器(scheduler)不是一個(gè)進(jìn)程,而是一套內(nèi)核中的調(diào)度策略和相關(guān)代碼的總稱。


1. 調(diào)度器不是進(jìn)程

  • 調(diào)度器不是一個(gè)進(jìn)程,它沒有自己的 PID,也不會(huì)出現(xiàn)在 ps/top 等進(jìn)程列表中。
  • 它是內(nèi)核代碼的一部分,始終運(yùn)行在內(nèi)核空間,由內(nèi)核負(fù)責(zé)調(diào)用和維護(hù)。

2. 調(diào)度器是什么?

  • 調(diào)度器(scheduler)是一套算法和實(shí)現(xiàn)代碼,決定了在任意時(shí)刻哪個(gè)進(jìn)程/線程可以獲得 CPU 運(yùn)行。
  • 它管理所有進(jìn)程/線程的狀態(tài)(就緒、運(yùn)行、阻塞等),并根據(jù)優(yōu)先級(jí)、調(diào)度策略等因素做出調(diào)度決策。

3. 調(diào)度器的實(shí)現(xiàn)位置

  • 主要代碼在 Linux 源碼的 kernel/sched/ 目錄下,比如:
    • core.c(核心框架)
    • fair.c(CFS 完全公平調(diào)度器,普通進(jìn)程用)
    • rt.c(實(shí)時(shí)調(diào)度器)
    • deadline.c(實(shí)時(shí) deadline 調(diào)度器)
  • 這些文件實(shí)現(xiàn)了不同的調(diào)度策略,比如 CFS、SCHED_FIFO、SCHED_RR、SCHED_DEADLINE 等。

4. 調(diào)度器的工作方式

  • 每當(dāng)需要切換進(jìn)程(比如時(shí)間片用完、進(jìn)程阻塞/喚醒、系統(tǒng)調(diào)用等),內(nèi)核會(huì)調(diào)用調(diào)度器的相關(guān)函數(shù)(如 schedule())。
  • 調(diào)度器會(huì)根據(jù)當(dāng)前所有可運(yùn)行進(jìn)程的狀態(tài)和優(yōu)先級(jí),選擇下一個(gè)要運(yùn)行的進(jìn)程。

5. 調(diào)度策略的含義

  • 調(diào)度策略是調(diào)度器內(nèi)部支持的不同算法,比如:
    • SCHED_OTHER(CFS,普通進(jìn)程)
    • SCHED_FIFO、SCHED_RR(實(shí)時(shí)進(jìn)程)
    • SCHED_DEADLINE(實(shí)時(shí) deadline)
  • 用戶和程序可以通過系統(tǒng)調(diào)用(如 sched_setscheduler)選擇進(jìn)程的調(diào)度策略。

6. 總結(jié)

Linux 進(jìn)程調(diào)度器不是進(jìn)程,而是內(nèi)核中的一套調(diào)度算法和實(shí)現(xiàn)代碼。它負(fù)責(zé)管理和切換所有進(jìn)程的運(yùn)行,是操作系統(tǒng)的核心組成部分。

Linux 系統(tǒng)運(yùn)行過程中是有多個(gè)調(diào)度器在工作嗎?

你的問題是:“Linux 系統(tǒng)運(yùn)行過程中是有多個(gè)調(diào)度器在工作嗎?”
簡(jiǎn)短回答:

不是有多個(gè)調(diào)度器在工作,而是有一個(gè)統(tǒng)一的調(diào)度框架,支持多種調(diào)度策略。所有 CPU(核)都用同一套調(diào)度器代碼,但可以為不同進(jìn)程/線程選擇不同的調(diào)度策略。


1. 調(diào)度器的整體結(jié)構(gòu)

  • Linux 只有一個(gè)調(diào)度器框架(scheduler framework),它是內(nèi)核的一部分,負(fù)責(zé)所有進(jìn)程/線程的調(diào)度。
  • 這個(gè)調(diào)度器框架支持多種調(diào)度策略(如 CFS、實(shí)時(shí)、deadline),這些策略在同一個(gè)調(diào)度器框架下協(xié)同工作。

2. 多核系統(tǒng)的調(diào)度

  • 在多核(SMP)系統(tǒng)中,每個(gè) CPU(核)都有自己的就緒隊(duì)列(runqueue),但調(diào)度器的實(shí)現(xiàn)代碼是同一套
  • 每個(gè) CPU 都會(huì)獨(dú)立運(yùn)行調(diào)度器的調(diào)度邏輯(比如定時(shí)器中斷觸發(fā) schedule()),但用的都是同樣的調(diào)度器代碼。
  • 進(jìn)程/線程可以在不同 CPU 之間遷移(load balance),這也是調(diào)度器負(fù)責(zé)的。

3. 多種調(diào)度策略的協(xié)作

  • 調(diào)度器支持多種調(diào)度策略,比如:
    • CFS(普通進(jìn)程,SCHED_OTHER)
    • 實(shí)時(shí)調(diào)度(SCHED_FIFO、SCHED_RR)
    • Deadline 調(diào)度(SCHED_DEADLINE)
  • 每個(gè)進(jìn)程/線程可以選擇自己的調(diào)度策略,調(diào)度器會(huì)根據(jù)優(yōu)先級(jí)和策略統(tǒng)一管理。
  • 例如,實(shí)時(shí)進(jìn)程優(yōu)先于普通進(jìn)程,deadline 進(jìn)程有自己的調(diào)度規(guī)則。

4. 源碼結(jié)構(gòu)

  • 主要在 kernel/sched/ 目錄下,不同文件實(shí)現(xiàn)不同策略,但都屬于同一個(gè)調(diào)度器框架。
  • 例如:
    • fair.c:CFS
    • rt.c:實(shí)時(shí)
    • deadline.c:deadline
    • core.c:調(diào)度器核心框架

5. 總結(jié)

  • Linux 只有一個(gè)調(diào)度器框架,但支持多種調(diào)度策略。
  • 所有 CPU 都用同一套調(diào)度器代碼,每個(gè)進(jìn)程/線程可以選擇不同的調(diào)度策略。
  • 不是“多個(gè)調(diào)度器”并行工作,而是“一個(gè)調(diào)度器支持多種策略”。

一個(gè)進(jìn)程是怎么選擇不同的調(diào)度策略的

非常好的問題!
一個(gè)進(jìn)程如何選擇不同的調(diào)度策略?
這涉及到用戶空間和內(nèi)核空間的接口,以及調(diào)度器的實(shí)現(xiàn)。下面詳細(xì)解答:


1. 什么是調(diào)度策略?

Linux 支持多種調(diào)度策略(policy),常見的有:

  • SCHED_OTHER(也叫 SCHED_NORMAL,CFS,普通進(jìn)程)
  • SCHED_FIFO(實(shí)時(shí),先進(jìn)先出)
  • SCHED_RR(實(shí)時(shí),時(shí)間片輪轉(zhuǎn))
  • SCHED_BATCH(批處理)
  • SCHED_IDLE(空閑進(jìn)程)
  • SCHED_DEADLINE(實(shí)時(shí) deadline)

2. 進(jìn)程如何選擇/更改調(diào)度策略?

A. 通過系統(tǒng)調(diào)用

  • 主要有兩個(gè)相關(guān)系統(tǒng)調(diào)用:
    • sched_setscheduler(pid, policy, &param)
      設(shè)置指定進(jìn)程的調(diào)度策略和優(yōu)先級(jí)
    • sched_setparam(pid, &param)
      只設(shè)置優(yōu)先級(jí),不改變策略

示例代碼:

#include <sched.h>
struct sched_param param;
param.sched_priority = 80; // 1~99 for real-time
sched_setscheduler(0, SCHED_FIFO, &param); // 把當(dāng)前進(jìn)程設(shè)置為實(shí)時(shí)FIFO策略

B. 通過命令行工具

  • chrt 命令可以在 shell 下設(shè)置進(jìn)程的調(diào)度策略和優(yōu)先級(jí):
chrt -f -p 80 1234   # 把 PID 1234 設(shè)置為 SCHED_FIFO,優(yōu)先級(jí)80
chrt -r 50 myprog    # 以 SCHED_RR 策略、優(yōu)先級(jí)50啟動(dòng) myprog
  • nice/renice 只能調(diào)整普通進(jìn)程的 nice 值,不能切換到實(shí)時(shí)策略。

3. 新進(jìn)程的策略繼承

  • fork() 出來的子進(jìn)程會(huì)繼承父進(jìn)程的調(diào)度策略和優(yōu)先級(jí)。
  • exec() 不會(huì)改變調(diào)度策略。

4. 內(nèi)核如何實(shí)現(xiàn)?

  • 每個(gè)進(jìn)程的 task_struct 結(jié)構(gòu)體里有 policy 字段,記錄當(dāng)前調(diào)度策略。
  • 系統(tǒng)調(diào)用 sched_setscheduler 會(huì)檢查權(quán)限(只有 root 可以設(shè)置實(shí)時(shí)策略),然后修改 policy 字段,并調(diào)整優(yōu)先級(jí)。
  • 調(diào)度器根據(jù) policy 字段決定該進(jìn)程用哪種調(diào)度算法。

5. 權(quán)限限制

  • 只有 root 用戶才能把進(jìn)程設(shè)置為實(shí)時(shí)調(diào)度(SCHED_FIFO、SCHED_RR、SCHED_DEADLINE),普通用戶只能用 SCHED_OTHER、SCHED_BATCH、SCHED_IDLE。

6. 查看進(jìn)程的調(diào)度策略

  • ps -eo pid,cmd,policy
  • chrt -p <pid>

7. 總結(jié)

進(jìn)程可以通過系統(tǒng)調(diào)用(如 sched_setscheduler)或 chrt 命令選擇/更改自己的調(diào)度策略。調(diào)度策略決定了進(jìn)程在調(diào)度器中的優(yōu)先級(jí)和調(diào)度方式。

像在 shell 中運(yùn)行的進(jìn)程, 調(diào)度策略是怎么被選擇的

非常好的問題!
在 shell(比如 bash、zsh)中直接運(yùn)行的進(jìn)程,它的調(diào)度策略是怎么被選擇的?


1. 默認(rèn)調(diào)度策略是什么?

  • 在 shell 中直接運(yùn)行的進(jìn)程(比如你輸入 ls、vimpython 等),
  • 默認(rèn)使用的是 SCHED_OTHER(也叫 SCHED_NORMAL,即 CFS 完全公平調(diào)度器)
  • 這種策略適用于絕大多數(shù)普通用戶進(jìn)程。

2. 為什么是 SCHED_OTHER?

  • shell 啟動(dòng)新進(jìn)程時(shí),調(diào)用的是 fork() + exec()。
  • 新進(jìn)程會(huì)繼承父進(jìn)程(即 shell 本身)的調(diào)度策略
  • shell 進(jìn)程本身也是普通用戶進(jìn)程,默認(rèn)就是 SCHED_OTHER。
  • 所以,你在 shell 里運(yùn)行的所有普通命令,默認(rèn)都是 SCHED_OTHER。

3. 優(yōu)先級(jí)(nice 值)如何確定?

  • 默認(rèn) nice 值是 0(可以用 nice 命令調(diào)整)。
  • 你可以用 nice -n 10 command 讓進(jìn)程以較低優(yōu)先級(jí)運(yùn)行。
  • 但這不會(huì)改變調(diào)度策略,仍然是 SCHED_OTHER,只是優(yōu)先級(jí)(nice)變了。

4. 如何在 shell 里改變調(diào)度策略?

  • 普通用戶不能直接用 shell 改為實(shí)時(shí)調(diào)度策略(SCHED_FIFO、SCHED_RR),需要 root 權(quán)限。
  • 可以用 chrt 命令(需要 root):
sudo chrt -f 80 ./myprog   # 以 SCHED_FIFO 策略、優(yōu)先級(jí)80運(yùn)行
  • 也可以用 nice 調(diào)整普通進(jìn)程的優(yōu)先級(jí):
nice -n 10 ./myprog        # 以較低優(yōu)先級(jí)運(yùn)行

5. 查看當(dāng)前進(jìn)程的調(diào)度策略

  • ps -eo pid,cmd,policychrt -p <pid> 可以看到進(jìn)程的調(diào)度策略。

6. 總結(jié)

在 shell 中直接運(yùn)行的進(jìn)程,默認(rèn)調(diào)度策略是 SCHED_OTHER(CFS),優(yōu)先級(jí)由 nice 值決定。只有通過 chrt(需要 root)等方式才能讓進(jìn)程使用實(shí)時(shí)調(diào)度策略。

Linux 調(diào)度策略有多個(gè), 那 cpu 輪轉(zhuǎn)的時(shí)候具體選擇哪個(gè)策略呢?

Linux 支持多種調(diào)度策略(如 SCHED_OTHER、SCHED_FIFO、SCHED_RR、SCHED_DEADLINE),那 CPU 輪轉(zhuǎn)(調(diào)度)時(shí),內(nèi)核是如何選擇用哪個(gè)策略的?

1. 調(diào)度器的“分層”選擇機(jī)制

Linux 調(diào)度器采用分層優(yōu)先級(jí)的方式來管理不同策略的進(jìn)程:

A. 實(shí)時(shí)優(yōu)先,普通次之

  1. 實(shí)時(shí)進(jìn)程(SCHED_FIFO、SCHED_RR、SCHED_DEADLINE)

    • 優(yōu)先級(jí)最高。只要有可運(yùn)行的實(shí)時(shí)進(jìn)程,調(diào)度器一定優(yōu)先調(diào)度實(shí)時(shí)進(jìn)程。
    • 多個(gè)實(shí)時(shí)進(jìn)程之間,再根據(jù)各自的策略和優(yōu)先級(jí)排序。
  2. 普通進(jìn)程(SCHED_OTHER、SCHED_BATCH、SCHED_IDLE)

    • 只有在沒有可運(yùn)行的實(shí)時(shí)進(jìn)程時(shí),調(diào)度器才會(huì)選擇普通進(jìn)程。
    • 普通進(jìn)程之間再用 CFS(完全公平調(diào)度器)等算法排序。

2. 調(diào)度器的選擇流程(簡(jiǎn)化版)

每當(dāng)需要調(diào)度(比如時(shí)間片用完、進(jìn)程阻塞/喚醒、系統(tǒng)調(diào)用等),調(diào)度器會(huì):

  1. 檢查所有可運(yùn)行的實(shí)時(shí)進(jìn)程隊(duì)列

    • 如果有 SCHED_DEADLINE 進(jìn)程,先選 deadline 最早的。
    • 否則,檢查 SCHED_FIFO/SCHED_RR 隊(duì)列,按優(yōu)先級(jí)(1~99)從高到低選擇。
    • SCHED_FIFO:同優(yōu)先級(jí)下先到先服務(wù),直到主動(dòng)讓出 CPU。
    • SCHED_RR:同優(yōu)先級(jí)下輪流分配時(shí)間片。
  2. 如果沒有可運(yùn)行的實(shí)時(shí)進(jìn)程

    • 選擇普通進(jìn)程隊(duì)列(CFS),按 vruntime(虛擬運(yùn)行時(shí)間)最小的進(jìn)程調(diào)度。
    • SCHED_BATCH、SCHED_IDLE 進(jìn)程優(yōu)先級(jí)更低,只有系統(tǒng)空閑時(shí)才會(huì)被調(diào)度。

3. 多核系統(tǒng)的情況

  • 每個(gè) CPU 都有自己的就緒隊(duì)列,但調(diào)度器的選擇邏輯是一樣的。
  • 進(jìn)程可以在不同 CPU 之間遷移,調(diào)度器會(huì)做負(fù)載均衡。

4. 源碼入口

  • 主要在 kernel/sched/core.cpick_next_task() 函數(shù)。
  • 偽代碼邏輯如下:
if (有可運(yùn)行的 SCHED_DEADLINE 進(jìn)程)
    選 deadline 最早的
else if (有可運(yùn)行的 SCHED_FIFO/SCHED_RR 進(jìn)程)
    選優(yōu)先級(jí)最高的實(shí)時(shí)進(jìn)程
else
    選 CFS 隊(duì)列中 vruntime 最小的普通進(jìn)程

5. 總結(jié)

CPU 輪轉(zhuǎn)時(shí),Linux 調(diào)度器總是優(yōu)先選擇實(shí)時(shí)策略(SCHED_DEADLINE > SCHED_FIFO/RR)的進(jìn)程。如果沒有實(shí)時(shí)進(jìn)程,才會(huì)選擇普通策略(SCHED_OTHER/CFS)的進(jìn)程。每種策略內(nèi)部再按各自規(guī)則排序。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 主要參考:Linux manual page - sched 概述 自從linux內(nèi)核2.6.23以來,默認(rèn)的進(jìn)程...
    啊呀喲嘿閱讀 926評(píng)論 0 0
  • Linux的調(diào)度策略區(qū)分實(shí)時(shí)進(jìn)程和普通進(jìn)程,實(shí)時(shí)進(jìn)程的調(diào)度策略是SCHED_FIFO和SCHED_RR,普通的,非...
    x1wan閱讀 2,205評(píng)論 0 1
  • Linux進(jìn)程的進(jìn)程級(jí)別分類 普通進(jìn)程 實(shí)時(shí)進(jìn)程 實(shí)時(shí)進(jìn)程的優(yōu)先級(jí)都高于普通進(jìn)程,除此之外,它們的調(diào)度策略也有所不...
    碼哥說閱讀 3,106評(píng)論 0 3
  • linux調(diào)度類:一共有5個(gè)調(diào)度類, 每個(gè)進(jìn)程都對(duì)應(yīng)一種調(diào)度策略, 每種策略又會(huì)對(duì)應(yīng)一種調(diào)度類(每個(gè)調(diào)度類可以對(duì)應(yīng)...
    sk邵楷閱讀 748評(píng)論 0 1
  • 調(diào)度程序負(fù)責(zé)決定哪個(gè)進(jìn)程投入運(yùn)行,何時(shí)運(yùn)行以及運(yùn)行多長(zhǎng)時(shí)間最大限度提供資源利用率,并且保證公平性 主要內(nèi)容 多任務(wù)...
    leon4ever閱讀 705評(píng)論 0 1

友情鏈接更多精彩內(nèi)容