當前位置:首頁 » 操作系統 » linux任務調度

linux任務調度

發布時間: 2022-04-11 23:43:47

linux內核怎麼調度系統

1.調度器的概述

多任務操作系統分為非搶占式多任務和搶占式多任務。與大多數現代操作系統一樣,Linux採用的是搶占式多任務模式。這表示對CPU的佔用時間由操作系統決定的,具體為操作系統中的調度器。調度器決定了什麼時候停止一個進程以便讓其他進程有機會運行,同時挑選出一個其他的進程開始運行。

2.調度策略

在Linux上調度策略決定了調度器是如何選擇一個新進程的時間。調度策略與進程的類型有關,內核現有的調度策略如下:

#define SCHED_NORMAL 0#define SCHED_FIFO 1#define SCHED_RR 2#define SCHED_BATCH 3/* SCHED_ISO: reserved but not implemented yet */#define SCHED_IDLE 5

0: 默認的調度策略,針對的是普通進程。
1:針對實時進程的先進先出調度。適合對時間性要求比較高但每次運行時間比較短的進程。
2:針對的是實時進程的時間片輪轉調度。適合每次運行時間比較長得進程。
3:針對批處理進程的調度,適合那些非交互性且對cpu使用密集的進程。
SCHED_ISO:是內核的一個預留欄位,目前還沒有使用
5:適用於優先順序較低的後台進程。
註:每個進程的調度策略保存在進程描述符task_struct中的policy欄位

3.調度器中的機制

內核引入調度類(struct sched_class)說明了調度器應該具有哪些功能。內核中每種調度策略都有該調度類的一個實例。(比如:基於公平調度類為:fair_sched_class,基於實時進程的調度類實例為:rt_sched_class),該實例也是針對每種調度策略的具體實現。調度類封裝了不同調度策略的具體實現,屏蔽了各種調度策略的細節實現。
調度器核心函數schele()只需要調用調度類中的介面,完成進程的調度,完全不需要考慮調度策略的具體實現。調度類連接了調度函數和具體的調度策略。

  • 武特師兄關於sche_class和sche_entity的解釋,一語中的。

  • 調度類就是代表的各種調度策略,調度實體就是調度單位,這個實體通常是一個進程,但是自從引入了cgroup後,這個調度實體可能就不是一個進程了,而是一個組

  • 4.schele()函數

    linux 支持兩種類型的進程調度,實時進程和普通進程。實時進程採用SCHED_FIFO 和SCHED_RR調度策略,普通進程採用SCHED_NORMAL策略。
    preempt_disable():禁止內核搶占
    cpu_rq():獲取當前cpu對應的就緒隊列。
    prev = rq->curr;獲取當前進程的描述符prev
    switch_count = &prev->nivcsw;獲取當前進程的切換次數。
    update_rq_clock() :更新就緒隊列上的時鍾
    clear_tsk_need_resched()清楚當前進程prev的重新調度標志。
    deactive_task():將當前進程從就緒隊列中刪除。
    put_prev_task() :將當前進程重新放入就緒隊列
    pick_next_task():在就緒隊列中挑選下一個將被執行的進程。
    context_switch():進行prev和next兩個進程的切換。具體的切換代碼與體系架構有關,在switch_to()中通過一段匯編代碼實現。
    post_schele():進行進程切換後的後期處理工作。

    5.pick_next_task函數

    選擇下一個將要被執行的進程無疑是一個很重要的過程,我們來看一下內核中代碼的實現
    對以下這段代碼說明:
    1.當rq中的運行隊列的個數(nr_running)和cfs中的nr_runing相等的時候,表示現在所有的都是普通進程,這時候就會調用cfs演算法中的pick_next_task(其實是pick_next_task_fair函數),當不相等的時候,則調用sched_class_highest(這是一個宏,指向的是實時進程),這下面的這個for(;;)循環中,首先是會在實時進程中選取要調度的程序(p = class->pick_next_task(rq);)。如果沒有選取到,會執行class=class->next;在class這個鏈表中有三種類型(fair,idle,rt).也就是說會調用到下一個調度類。

  • static inline struct task_struct *pick_next_task(struct rq *rq){ const struct sched_class *class; struct task_struct *p; /*

  • * Optimization: we know that if all tasks are in

  • * the fair class we can call that function directly:

  • *///基於公平調度的普通進程

  • if (likely(rq->nr_running == rq->cfs.nr_running)) {

  • p = fair_sched_class.pick_next_task(rq); if (likely(p)) return p;

  • }//基於實時調度的實時進程

  • class = sched_class_highest; for ( ; ; ) {

  • p = class->pick_next_task(rq); //實時進程的類

  • if (p) return p; /*

  • * Will never be NULL as the idle class always

  • * returns a non-NULL p:

  • */

  • class = class->next; //rt->next = fair; fair->next = idle

  • }

  • }

  • 在這段代碼中體現了Linux所支持的兩種類型的進程,實時進程和普通進程。回顧下:實時進程可以採用SCHED_FIFO 和SCHED_RR調度策略,普通進程採用SCHED_NORMAL調度策略。
    在這里首先說明一個結構體struct rq,這個結構體是調度器管理可運行狀態進程的最主要的數據結構。每個cpu上都有一個可運行的就緒隊列。剛才在pick_next_task函數中看到了在選擇下一個將要被執行的進程時實際上用的是struct rq上的普通進程的調度或者實時進程的調度,那麼具體是如何調度的呢?在實時調度中,為了實現O(1)的調度演算法,內核為每個優先順序維護一個運行隊列和一個DECLARE_BITMAP,內核根據DECLARE_BITMAP的bit數值找出非空的最高級優先隊列的編號,從而可以從非空的最高級優先隊列中取出進程進行運行。
    我們來看下內核的實現

  • struct rt_prio_array {

  • DECLARE_BITMAP(bitmap, MAX_RT_PRIO+1); /* include 1 bit for delimiter */

  • struct list_head queue[MAX_RT_PRIO];

  • };

  • 數組queue[i]裡面存放的是優先順序為i的進程隊列的鏈表頭。在結構體rt_prio_array 中有一個重要的數據構DECLARE_BITMAP,它在內核中的第一如下:

  • define DECLARE_BITMAP(name,bits)

  • unsigned long name[BITS_TO_LONGS(bits)]

  • 5.1對於實時進程的O(1)演算法

    這個數據是用來作為進程隊列queue[MAX_PRIO]的索引點陣圖。bitmap中的每一位與queue[i]對應,當queue[i]的進程隊列不為空時,Bitmap的相應位就為1,否則為0,這樣就只需要通過匯編指令從進程優先順序由高到低的方向找到第一個為1的位置,則這個位置就是就緒隊列中最高的優先順序(函數sched_find_first_bit()就是用來實現該目的的)。那麼queue[index]->next就是要找的候選進程。
    如果還是不懂,那就來看兩個圖

    由結果可以看出當nice的值越小的時候,其睡眠時間越短,則表示其優先順序升高了。

    7.關於獲取和設置優先順序的系統調用:sched_getscheler()和sched_setscheler

  • #include <sched.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#define DEATH(mess) { perror(mess); exit(errno); }void printpolicy (int policy){ /* SCHED_NORMAL = SCHED_OTHER in user-space */


  • if (policy == SCHED_OTHER) printf ("policy = SCHED_OTHER = %d ", policy); if (policy == SCHED_FIFO) printf ("policy = SCHED_FIFO = %d ", policy); if (policy == SCHED_RR) printf ("policy = SCHED_RR = %d ", policy);

  • }int main (int argc, char **argv){ int policy; struct sched_param p; /* obtain current scheling policy for this process */

  • //獲取進程調度的策略

  • policy = sched_getscheler (0);

  • printpolicy (policy); /* reset scheling policy */


  • printf (" Trying sched_setscheler... ");

  • policy = SCHED_FIFO;

  • printpolicy (policy);

  • p.sched_priority = 50; //設置優先順序為50

  • if (sched_setscheler (0, policy, &p))

  • DEATH ("sched_setscheler:"); printf ("p.sched_priority = %d ", p.sched_priority); exit (0);

  • }

  • 輸出結果:

  • [root@wang schele]# ./get_schele_policy policy = SCHED_OTHER = 0


  • Trying sched_setscheler...

  • policy = SCHED_FIFO = 1

  • p.sched_priority = 50

  • 可以看出進程的優先順序已經被改變。

❷ linux進程調度的三種策略是什麼

進程調度策略就是調度系統種哪一個進程來CPU運行。這種調度分2層考慮。 第一層,進程狀態這個是最優先考慮的,也就是說優先順序最高的。在linux中只有就緒態的進程才有可能會被調度選中然後佔有CPU,其它狀態的進程不可能佔有的到CPU。下面是linux中進程的狀態TASK_RUNNING:就緒狀態,得到CPU就可以運行。
TASK_INTERRUPTIBLE:淺度睡眠,資源到位或者受到信號就會變成就緒態。
TASK_UNINTERRUPTIBLE:深度睡眠,資源到位就會進入就緒態,不響應信號。
TASK_ZOMBIE:僵死態,進程exit後。
TASK_STOPPED:暫停態,收到SIG_CONT信號進入就緒態。 第二層,其實真正在操作系統中的實現,就是所有就緒態進程鏈接成一個隊列,進程調度時候只會考慮這個隊列中的進程,對其它的進程不考慮,這就實現了第一層中的要求。接下來就是就緒隊列內部各個進程的競爭了。 Linux採用3種不同的調度政策,SCHED_FIFO(下面簡寫成FIFO,先來先服務),SCHED_RR(簡寫成RR,時間片輪流),SCHED_OTHER(下面簡寫成OTHER)。這里大家就能看出一個問題,採用同等調度政策的進程之間自然有可比性,Linux3種調度政策並存,那麼不同調度政策間的進程如何比較呢?可以說他們之間根本就沒有可比性。其實在調度時候,調度只看一個指標,那就是各個進程所具有的權值,權值最大的且在可執行隊列中排在最前面的就會被調度執行。而權值的計算才會設計到各方面因素,其中調度政策可以說在計算權值中,份量是最重的。 為什麼Linux要這么干呢?這是由於事務的多樣性決定的,進程有實時性進程和非實時性的進程2種,FIFO和RR是用來支持實時性進程的調度,我們看一下這3種政策下權值的計算公式就明白了:FIFO和RR計算公式,權值=1000+進程真正的運行時間OTHER計算公式,當時間片為0時,權值=0.當時間片不為0時候,權值=剩餘時間片+20-nice,同時如果是內核線程有+1的小加分,這是因為內核線程無需用戶空間的切換,所以給它加了一分,獎勵他在進程切換時候開銷小的功勞。時間片好理解,那麼nice這個值,用過linux系統的人都知道,這是一個從unix下繼承過來的概念,表示謙讓度,是一個從20~-19的數,可以通過nice和renice指令來設置。從代碼中也能看到值越小就越不會謙讓他人。 從這里我們看出FIFO和RR至少有1000的基數,所以在有FIFO和RR調度政策進程存在時,OTHER進程是沒有機會被調度的到的。從權值計算公式同時也能看出,FIFO先來先服務的調度政策滿足了,但RR這個時間片輪流的調度如果按照這種權值計算是不能滿足時間片輪流這一概念的。這里只是權值的計算,在調度時候對RR政策的進程特殊處理。 以上都是權值計算,下面看看真正的調度過程,首先是對RR政策進程的特殊處理,如果當前進程採用的RR政策,那麼看他的時間片是否用完,用完了就踢到就緒隊列尾部,同時恢復他的時間片。然後是便利整個就緒隊列,找到第一個權值最大的進程來運行。 整體調度效果就是:如果有FIFO和RR政策的進程,就優先調度他們2個,他們之間看已執行時間長短決定勝負,而2種政策內部則遵守各自調度政策。而OTHER只有在前面2種不存在於就緒隊列時候才有可能執行,他們實際也是輪流執行,但他們之間是靠剩餘時間和NICE值來決定勝負。同時就緒隊列中排在最前面的最優先考慮在同樣權值情況下。

❸ linux的任務調度機制是什麼

調度程序運行時,要在所有可運行狀態的進程中選擇最值得運行的進程投入運行。選擇進程的依據是什麼呢?在每個進程的task_struct結構中有以下四 項:policy、priority、counter、rt_priority。這四項是選擇進程的依據。其中,policy是進程的調度策略,用來區分 實時進程和普通進程,實時進程優先於普通進程運行;priority是進程(包括實時和普通)的靜態優先順序;counter是進程剩餘的時間片,它的起始 值就是priority的值;由於counter在後面計算一個處於可運行狀態的進程值得運行的程度goodness時起重要作用,因此,counter 也可以看作是進程的動態優先順序。rt_priority是實時進程特有的,用於實時進程間的選擇。
Linux用函數goodness()來衡量一個處於可運行狀態的進程值得運行的程度。該函數綜合了以上提到的四項,還結合了一些其他的因素,給每個處於 可運行狀態的進程賦予一個權值(weight),調度程序以這個權值作為選擇進程的唯一依據。關於goodness()的情況在後面將會詳細分析。

❹ linux操作系統進程調度

Linux進程調度採用的是搶占式多任務處理,所以進程之間的掛起和繼續運行無需彼此之間的協作。

❺ 在Linux 9中,cron用來周期性的進行任務調度,請列出cron任務的格式,如果要月運行一次,怎麼設置請說

1)、cron的格式為
minute hour day month dayofweek command
* * * * *
入果要一月運行一次的話,格式是:
N(0-59) N(0-23) N(1-31) * * command
也可以舉例說明。

2)、法一:用crontab命令逐行進行輸入,按「ctrl+d」退出。
法二:用crontab –e 命令,用編輯器對文件進行編輯。
可用crontab –l 顯示cron信息
3)、/etc/init.d/crond 文件是cron 的服務程序運行腳本
/etc/crontab是Linux系統維護所需的任務,一般不需要人為修改;
/etc/下的 cron.daily, cron.hourly, cron.monthly, cron.weekly的目錄,存放相應的系統執行任務;
/var/spool/cron/用戶名 是保存此用戶的cron任務的文件。
還有不會的請參考《linux就該這么學》,針對各種linux疑難雜症,幫助linux學習者。

❻ linux的進程調度採用的是

Linux進程調度採用的是搶占式多任務處理,所以進程之間的掛起和繼續運行無需彼此之間的協作。
在一個如linux這樣的多任務系統中,多個程序可能會競爭使用同一個資源,在這種情況下,我們認為,執行短期的突發性工作並暫停運行以等待輸入的程序,要比持續佔用處理器以進行計算或不斷輪詢系統以查看是否有輸入到達的程序要更好。我們稱表現好的程序為nice程序,而且在某種意義上,這個nice 是可以被計算出來的。操作系統根據進程的nice值來決定它的優先順序,一個進程的nice值默認為0並將根據這個程序的表現不斷變化。長期不間斷運行的程序的優先順序一般會比較低。

❼ linux 調整CPU程序調度的幾種方法

一,使用taskset充分利用多核cpu,讓cpu的使用率均衡到每個cpu上
#taskset
-p, 設定一個已存在的pid,而不是重新開啟一個新任務
-c, 指定一個處理,可以指定多個,以逗號分隔,也可指定范圍,如:2,4,5,6-8。
1,切換某個進程到指定的cpu上
taskset -cp 3 13290
2,讓某程序運行在指定的cpu上
taskset -c 1,2,4-7 tar jcf test.tar.gz test
需要注意的是,taskset -cp 3 13290在設定一個已經存在的pid時,子進程並不會繼承父進程的,
因此像tar zcf xxx.tar.gz xxx這樣的命令,最好在啟動時指定cpu,如果在已經啟動的情況下,則需要指定tar調用的gzip進程。
二,使用nice和renice設置程序執行的優先順序
格式:nice [-n 數值] 命令
nice 指令可以改變程序執行的優先權等級。指令讓使用者在執行程序時,指定一個優先等級,稱之為 nice 值。
這個數值從最高優先順序的-20到最低優先順序的19。負數值只有 root 才有權力使。
一般使用者,也可使用 nice 指令來做執行程序的優先順序管理,但只能將nice值越調越高。
可以通過二種方式來給某個程序設定nice值:
1,開始執行程序時給定一個nice值,用nice命令
2,調整某個運行中程序的PID的nice值,用renice命令
通常通過調高nice值來備份,為的是不佔用非常多的系統資源。
例:
nice -n 10 tar zcf test.tar.gz test
由nice啟動的程序,其子進程會繼承父進程的nice值。
查看nice值
# nice -n -6 vim test.txt &
# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 19427 2637 0 75 0 – 16551 wait pts/6 00:00:00 bash
4 T 0 21654 19427 0 71 -6 – 23464 finish pts/6 00:00:00 vim
renice調整運行中程序的nice值
格式:renice [nice值] PID
三,使用ulimit限制cpu佔用時間
注意,ulimit 限制的是當前shell進程以及其派生的子進程。因此可以在腳本中調用ulimit來限制cpu使用時間。
例如,限制tar的cpu佔用時間,單位秒。
# cat limit_cpu.sh
ulimit -SHt 100
tar test.tar.gz test
如果tar佔用時間超過了100秒,tar將會退出,這可能會導致打包不完全,因此不推薦使用ulimit對cpu佔用時間進行限制。
另外,通過修改系統的/etc/security/limits配置文件,可以針對用戶進行限制。
四,使用程序自帶的對cpu使用調整的功能
某些程序自帶了對cpu使用調整的功能,比如nginx伺服器,通過其配置文件,可以為工作進程指定cpu,如下:
worker_processes 3;
worker_cpu_affinity 0001 0010 0100 1000;
這里0001 0010 0100 1000是掩碼,分別代表第1、2、3、4顆cpu核心,這就使得cpu的使用比較平均到每個核心上。

❽ linux中設置任務調度兩種方法:/etc/crontab文件和crontab -e命令,兩種方式有什功能上的區別

修改/etc/crontab這種方法只有root用戶能用,這種方法更加方便與直接直接給其他用戶設置計劃任務,而且還可以指定執行shell等等,推薦這種方法。

crontab -e這種所有用戶都可以使用,普通用戶也只能為自己設置計劃任務。

熱點內容
捏泡膠解壓 發布:2024-11-15 10:55:07 瀏覽:802
linux文件最後一行 發布:2024-11-15 10:44:11 瀏覽:612
怎麼根據序列號查配置 發布:2024-11-15 10:31:52 瀏覽:348
mysql查看資料庫位置 發布:2024-11-15 10:25:16 瀏覽:439
需要學Python 發布:2024-11-15 10:23:41 瀏覽:836
如何製作安卓平板軟體 發布:2024-11-15 10:23:39 瀏覽:215
手機忘記密碼被鎖預示著什麼 發布:2024-11-15 10:22:15 瀏覽:193
android圖片管理 發布:2024-11-15 10:13:02 瀏覽:9
演算法微調 發布:2024-11-15 10:07:44 瀏覽:542
python列表查詢 發布:2024-11-15 10:06:08 瀏覽:133