進程就是資源的集合體,既包括打開的文件,收到的信號,占用的地址空間這些軟資源,也包括對cpu,內存的占用這些硬資源。而線程只是代碼的一個執行流,與其他線程共享某些資源。
調度算法的設計目標,讓cpu上的指令流更有價值,這就需要,
1,調度必須盡可能快的完成,占用盡可能少的cpu時間
2,交互進程盡快得到響應
3,批處理進程盡快的處理完成
這就需要調度算法在盡量短的時間內選出the most valueable的進程,也就是優先級最高的進程。並進行進程的切換,並且,進程切換的開銷應盡可能小,主要包括頁表的切換和寄存器的切換。
在內核中用task_struct 來描述一個進程,
struct task_struct{
1082 int lock_depth; /* BKL lock depth */
1129 struct mm_struct *mm, *active_mm;
1215 /* CPU-specific state of this task */
1216 struct thread_struct thread;
1217 /* filesystem information */
1218 struct fs_struct *fs;
1219 /* open file information */
1220 struct files_struct *files;
1221 /* namespaces */
1222 struct nsproxy *nsproxy;
1223 /* signal handlers */
而ret_from_fork
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
不明白。
所謂創建一個進程,就是分配合適的pid,並為之創建task_struct和內核stack,並把stack裡的pt_regs設置下,返回的時候好恢復到調用點,並選擇性的繼承父進程的資源。
schedule()
1,通過o(1)算法選出優先級最高的進程。
每個cpu有一個run_queue結構,保存有進程優先級的位圖,通過位圖索引到對應的list,取鏈首進程。
2,switch_context()調用switch_mm()切換頁表,switch_to()從上一個進程的處理器狀態切換到新進程,包括保存恢復棧信息和寄存器信息
內核的搶占性
thread_info結構中的preemt_count字段表明當前進程是否可以被搶占
24 #define preempt_count() (current_thread_info()->preempt_count)
30 #define preempt_disable() \
31 do { \
32 inc_preempt_count(); \
33 barrier(); \
34 } while (0)
內核的搶占點
1,中斷處理程序返回內核空間
2,內核代碼再次有可搶占性,如釋放一個鎖
3,顯示調用schedule,kernel trust kernel code,由調用者保證代碼可以安全的被搶占
4,內核中的任務阻塞,隱式調用schedule()
對應的用戶空間的搶占發生在
1,系統調用返回
2,中斷處理返回到用戶空間