鍍金池/ 教程/ Linux/ shell 學(xué)習(xí)五十五天----進(jìn)程記賬
shell 學(xué)習(xí)四十一天----列出文件 ls 和 od 命令
shell 學(xué)習(xí)小結(jié)
shell 學(xué)習(xí)第二十八天----case 語句
shell 學(xué)習(xí)四十四天----尋找文件
shell 學(xué)習(xí)三十五天----波浪號展開與通配符
shell 學(xué)習(xí)三十八天----執(zhí)行順序和 eval
shell 學(xué)習(xí)四十八天----文件校驗和匹配
shell 學(xué)習(xí)四十天----awk 的驚人表現(xiàn)
shell 學(xué)習(xí)第十一天----sed 正則的精確控制
shell 學(xué)習(xí)第十七天----awk 命令
shell 學(xué)習(xí)三十九天----內(nèi)建命令
shell 學(xué)習(xí)四十五天----xargs
shell 學(xué)習(xí)三十七天----引用
shell 學(xué)習(xí)第十六天----join 練習(xí)
shell 學(xué)習(xí)第二十四天----提取開頭或結(jié)尾數(shù)行
shell 學(xué)習(xí)第九天----分組
shell 學(xué)習(xí)第五天----基本的 I/O 重定向
shell 學(xué)習(xí)第十五天----使用 cut 選定字段
shell 學(xué)習(xí)四十六天----文件系統(tǒng)的空間信息 df 和 du 命令
shell 學(xué)習(xí)第八天----擴展正則表達(dá)式 (ERE)
shell 學(xué)習(xí)第十九天----文本塊排序
shell 學(xué)習(xí)第二十一天----重新格式化段落
shell 學(xué)習(xí)三十六天----命令替換
shell 學(xué)習(xí)第二十天----sort 的其他內(nèi)容以及 uniq 命令
shell 學(xué)習(xí)四十二天----使用 touch 更新文件時間
shell 學(xué)習(xí)五十一天----top 命令查看進(jìn)程列表
shell 學(xué)習(xí)第一天
shell 學(xué)習(xí)五十四天----進(jìn)程系統(tǒng)調(diào)用的追蹤 strace
shell 學(xué)習(xí)五十天----查看進(jìn)程 ps 命令
shell 學(xué)習(xí)第二十七天----退出狀態(tài)和 if 語句
shell 學(xué)習(xí)第二十三天----打印
shell 學(xué)習(xí)三十三天----關(guān)于重定向
shell 學(xué)習(xí)四十九天----進(jìn)程建立
shell 學(xué)習(xí)第三十天----break,continue,shift,getopts
shell 學(xué)習(xí)五十五天----進(jìn)程記賬
shell 學(xué)習(xí)總結(jié)一
shell 學(xué)習(xí)第二十六天----變量與算數(shù)
shell 學(xué)習(xí)第二十二天----計算行數(shù), 字?jǐn)?shù)以及字符數(shù)
shell 學(xué)習(xí)五十八天----/proc 文件系統(tǒng)
shell 學(xué)習(xí)第二十五天----神器的管道符
shell 學(xué)習(xí)第三十二天----read 讀取一行
sheel 學(xué)習(xí)第三天
shell 學(xué)習(xí)----小結(jié)
shell 學(xué)習(xí)第十八天----文本排序
shell 學(xué)習(xí)第三十一天----函數(shù)問題
shell 學(xué)習(xí)第十天----sed 查找與替換
shell 學(xué)習(xí)四十三天----臨時性文件的建立與使用
shell 學(xué)習(xí)四十七天----文件比較 cmp,diff,patch
shell 學(xué)習(xí)三十四天----printf 詳解
shell 學(xué)習(xí)五十七天 ----linux 任務(wù)管理,針對上一講的總結(jié)和擴展
shell 學(xué)習(xí)第六天----小結(jié)
shell 學(xué)習(xí)第十三天----sed 案例分析
shell 學(xué)習(xí)第七天----基礎(chǔ)正則表達(dá)式 (BRE)
shell 學(xué)習(xí)第十二天----行與字符串
shell 學(xué)習(xí)小結(jié)四
shell 學(xué)習(xí)第二十九天----循環(huán)
shell 學(xué)習(xí)五十二天----刪除進(jìn)程 kill 命令
shell 學(xué)習(xí)五十六天----延遲進(jìn)程調(diào)度
shell 學(xué)習(xí)第四天----華麗的 printf 輸出
shell 學(xué)習(xí)第十五天----join 連接字段
shell 學(xué)習(xí)完結(jié)篇----希望你能看到
shell 學(xué)習(xí)第二天
shell 學(xué)習(xí)五十三天----捕獲信號 trap

shell 學(xué)習(xí)五十五天----進(jìn)程記賬

linux 進(jìn)程調(diào)度的實現(xiàn) ---- 進(jìn)程記賬

linux 進(jìn)程調(diào)度的實現(xiàn)一共由四部分組成:

  1. 時間記賬 (就是記錄進(jìn)程已經(jīng)運行了多長時間,還要運行多長時間)
  2. 進(jìn)程選擇 (加入紅黑樹)
  3. 調(diào)度器入口
  4. 睡眠和喚醒

進(jìn)程記賬:就是記錄一個進(jìn)程占用處理器資源的時間長度。既然要記錄,那么就需要存在在一個位置,內(nèi)核說,放在 sched_entity 結(jié)構(gòu)中吧。我們當(dāng)然要聽內(nèi)核的....

至于 sched_entity 這個結(jié)構(gòu)的源碼我就不貼了,但是里面有一個 vruntime 成員變量,這個成員變量可看成 virtual run time,正確名字是虛擬實時。

這個 vruntime 變量就是用來記錄進(jìn)程已經(jīng)運行的時間長短,或者說,占用處理器已經(jīng)多長時間了。那么這個事件越長就越證明運行的時間越長,就越容易被其他的進(jìn)程擠掉,也就是,其他進(jìn)程容易搶占進(jìn)來。linux 系統(tǒng)對于進(jìn)城的調(diào)度室要看這個變量來采取行動的。那么這個虛擬實時 (時間值) 怎么計算出來的?(這個計算過程就是進(jìn)程記賬的過程),內(nèi)核使用 update_curr() 函數(shù)來實現(xiàn)這個過程。

源碼

```static void update_curr(struct cfs_rq cfs_rq) { struct sched_entity curr = cfs_rq->curr; u64 now = rq_of(cfs_rq)->clock_task; unsigned long delta_exec; if (unlikely(!curr)) return; /*

  • Get the amount of time the current task was running
  • since the last time we changed load (this cannot
  • overflow on 32 bits): / delta_exec = (unsigned long)(now - curr->exec_start); if (!delta_exec) return; __update_curr(cfs_rq,curr,delta_exec); curr->exec_start = now; if (entity_is_task(curr)) { struct task_struct curtask = task_of(curr); trace_sched_stat_runtime(curtask,delta_exec,curr->vruntime); cpuacct_charge(curtask,delta_exec); account_group_exec_runtime(curtask,delta_exec); } account_cfs_rq_runtime(cfs_rq,delta_exec); }

這個 update_curr 函數(shù)中存在這么幾個變量和函數(shù)。curr 是一個 sched_entity 結(jié)構(gòu)指針,接收函數(shù)傳進(jìn)的參數(shù)。函數(shù)參數(shù)那個結(jié)構(gòu)是什么? 搞不明白,反正就是吧其中的一個成員復(fù)制 curr 變量。看名字可以知道是指進(jìn)程當(dāng)前的狀態(tài) (當(dāng)然,包括虛擬實時)。接著定義了一個無符號長整型變量 delta_exec,查一下 delta 有增量的意思,而 exec 是執(zhí)行,那么從名字上看就是值執(zhí)行的增量 (就是時間的增量)。然后,看到 delta_exec 被賦值為 nowexec_start 的差值,exec_start 這個可以知道這時開始,現(xiàn)在減開始的,那就是已經(jīng)運行的時間。最后執(zhí)行__update_curr 函數(shù)將當(dāng)前的進(jìn)程賬本,和已經(jīng)運行的時間作為參數(shù)傳如,先來看一下__update_curr() 這個函數(shù):

```static inline void __update_curr(struct cfs_rq cfs_rq,struct sched_entity curr, unsigned long delta_exec) { unsigned long delta_exec_weighted; schedstat_set(curr->statistics.exec_max, max((u64)delta_exec,curr->statistics.exec_max)); curr->sum_exec_runtime += delta_exec; schedstat_add(cfs_rq,exec_clock,delta_exec); delta_exec_weighted = calc_delta_fair(delta_exec,curr); curr->vruntime += delta_exec_weighted; update_min_vruntime(cfs_rq); #if defined CONFIG_SMP && defined CONFIG_FAIR_GROUP_SCHED cfs_rq->load_unacc_exec_time += delta_exec; #endif }



分析一下:傳入的參數(shù) `curr`,`delta_exec`,執(zhí)行了 `calc_delta_fair`,從名字入手,這是計算,計算什么? 增量,還是公平的,那就是加入了權(quán)重,這樣計算出了權(quán)重值。接著在 `vruntime` 上加上權(quán)重,這就是進(jìn)程運行的時間,記賬完成。