您好,登錄后才能下訂單哦!
這篇文章主要講解了“linux進程調度源碼是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“linux進程調度源碼是什么”吧!
下面是進程調度函數及其相關函數的代碼。
void schedule(void)
{
int i,next,c;
struct task_struct ** p;
/* check alarm, wake up any interruptible tasks that have got a signal */
// 處理進程的信號和狀態
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if (*p) {
/*
alarm的值是調用alarm函數設置的,見alarm函數,進程可以調用alarm函數,設置一個時間,
然后到期后會觸發alram信號,alarm < jiffies說明過期了。設置alarm信號
*/
if ((*p)->alarm && (*p)->alarm < jiffies) {
(*p)->signal |= (1<<(SIGALRM-1));
(*p)->alarm = 0;
}
/*
_BLOCKABLE為可以阻塞的信號集合,blocked為當前進程設置的阻塞集合,相與
得到進程當前阻塞的集合,即排除進程阻塞了不能阻塞的信號,然后取反得到可以接收的
信號集合,再和signal相與,得到當前進程當前收到的信號。如果進程處于掛起狀態,則改成可執行
*/
if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) &&
(*p)->state==TASK_INTERRUPTIBLE)
(*p)->state=TASK_RUNNING;
}
/* this is the scheduler proper: */
// 開始調度,選擇合適的進程執行
while (1) {
c = -1;
next = 0;
i = NR_TASKS;
p = &task[NR_TASKS];
while (--i) {
if (!*--p)
continue;
// 找出時間片最大的進程,說明他執行的時間最短
if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
c = (*p)->counter, next = i;
}
// 還有進程需要執行,c大于等于0
if (c) break;
// 沒有break說明c等于0,即所有的進程時間片已經執行完,需要重新設置
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if (*p)
// 優先級越高,執行的時間越長,被選中執行的機會越大
(*p)->counter = ((*p)->counter >> 1) +
(*p)->priority;
}
// 切換進程
switch_to(next);
}
#define switch_to(n) {\
struct {long a,b;} __tmp; \
// ecx是第n個進程對應的pcb首地址,判斷切換的下一個進程是不是就是當前執行的進程,是就不需要切換了
__asm__("cmpl %%ecx,_current\n\t" \
"je 1f\n\t" \
// 把第n個進程的tss選擇子復制到__tmp.b
"movw %%dx,%1\n\t" \
// 更新current變量,使current變量執行ecx,ecx指向task[n]
"xchgl %%ecx,_current\n\t" \
// ljmp 跟一個tss選擇子實現進程切換
"ljmp %0\n\t" \
// 忽略
"cmpl %%ecx,_last_task_used_math\n\t" \
"jne 1f\n\t" \
"clts\n" \
"1:" \
::"m" (*&__tmp.a),"m" (*&__tmp.b), \
"d" (_TSS(n)),"c" ((long) task[n])); \
}
int sys_alarm(long seconds)
{
int old = current->alarm;
if (old)
old = (old - jiffies) / HZ;
// 1秒等于100個jiffies
current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;
return (old);
}
// 修改進程執行的優先級,滿足條件的情況下increment越大優先權越低
int sys_nice(long increment)
{
if (current->priority-increment>0)
current->priority -= increment;
return 0;
}
每個進程有一個執行的時間,每次時鐘中斷會減少一個單位的時間。如果時間用完則直接重新調度,否則進程可以繼續執行。進程調度的時候,系統會選擇時間最長的進程,防止有的進程得不到執行,當所有進程的時間片都消耗完畢,則重新計算時間。
do_timer函數
if ((--current->counter)>0) return;
current->counter=0;
感謝各位的閱讀,以上就是“linux進程調度源碼是什么”的內容了,經過本文的學習后,相信大家對linux進程調度源碼是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。