一、contextswitch的概念
contextswitch(上下文切換)是指操作系統暫停當前正在執行的進程,保存該進程的狀態(上下文),並將CPU執行的狀態切換到另一個就緒進程上,恢復該進程的狀態,使其繼續執行。
在單核CPU的情況下,CPU的時間片被劃分成若干個時間片,每個時間片都由一個進程佔用,進程執行完或者被喚醒後,就進行contextswitch。
在多核CPU的情況下,多個進程同時被處理,每個核心上的進程都有自己的時間片,所以contextswitch的操作會在多個核心之間進行。
二、contextswitch的過程
contextswitch的過程大概可以分為以下幾個步驟:
1、當前進程被暫停。
2、內核中將當前進程的上下文(CPU狀態、寄存器信息等)保存到進程控制塊(PCB)中。
3、進程調度器選取下一個就緒進程。
4、內核中將下一個進程的上下文從進程控制塊中恢復,設置為CPU的當前上下文。
5、新進程開始執行。
三、contextswitch的作用
1、實現多任務:在多任務操作系統中,contextswitch提供了用於切換不同進程的機制,使得多個進程可以在CPU上交替執行,實現並行處理。
2、避免死鎖:當某個進程發生死鎖時,其它進程可以通過contextswitch切換到其它進程,在一定程度上避免了死鎖的發生。
3、提升系統的響應性:contextswitch可以讓不同的進程依次使用CPU,從而提高系統的並發程度,進而提升系統的響應速度。
四、contextswitch的代碼實例
void contextswitch(task_struct *prev, task_struct *next) { /* 保存進程上下文 */ __asm__ __volatile__("pushl %%ebp\n\t" "movl %%esp,%[prev_sp]\n\t" "movl %[next_sp],%%esp\n\t" "cmpl $0,%[prev_pid]\n\t" "jne 1f\n\t" /* 第一次進入,跳轉至label 1*/ "movl %[next_entry],%%eax\n\t" "jmp *%%eax\n\t" /* 跳轉至下一個進程的代碼段 */ "1:\tmovl %[prev_pid],%%eax\n\t" "movl $(prev_task_exit),%%ebx\n\t" "movl %%ebx,%%eax\n\t" "call *%%eax\n\t" /* 執行上一個進程的退出處理函數 */ "movl %[next_entry],%%eax\n\t" "jmp *%%eax\n\t" /* 跳轉至下一個進程的代碼段 */ : [prev_sp] "=m"(prev->cpu_context.sp), [prev_pid] "=m"(prev->pid), [next_sp] "=m"(next->cpu_context.sp), [next_entry] "=m"(next->cpu_context.pc) : : "%eax", "%ebx", "memory"); }
五、contextswitch的優化
contextswitch操作是系統開銷較大的操作,部分操作系統在此方面進行了優化,例如:
1、採用多級反饋隊列調度算法,調整優先級,使高優先級進程儘早執行,以減小contextswitch的開銷。
2、在系統內核中使用協程(coroutine),協程之間的切換比進程、線程之間的切換更為輕量,從而減小了contextswitch的開銷。
3、使用Fiber,Fiber是用戶模式下的線程,一般不需要進行內核態與用戶態的切換,因此contextswitch的開銷可以顯著降低。
原創文章,作者:QJMTP,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/333090.html