Linux fork()一个进程内核态的变化
【前言】用戶態(tài)的變化,耳熟能詳不在贅述。現(xiàn)在支持讀時共享,寫時復制。
一、內核態(tài)的變化
1、fork一個子進程代碼
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char * argv[]) {int pid;/* fork another process */pid = fork();if (pid < 0) { /* error occurred */fprintf(stderr,"Fork Failed!");exit(-1);} else if (pid == 0) {/* child process */printf("This is Child Process!\n");} else { /* parent process */printf("This is Parent Process!\n");/* parent will wait for the child to complete*/wait(NULL);printf("Child Complete!\n");} }2、創(chuàng)建一個新進程在內核中的執(zhí)行過程
fork、vfork和clone三個系統(tǒng)調用都可以創(chuàng)建一個新進程,而且都是通過調用do_fork來實現(xiàn)進程的創(chuàng)建;
3、Linux通過復制父進程來創(chuàng)建一個新進程,那么這就給我們理解這一個過程提供一個想象的框架:
(1)復制一個PCB——task_struct
? ? ? ? ? ? ? ? ? ? err = arch_dup_task_struct(tsk, orig);
? ? ? ? ? ? ? ?(2)要給新進程分配一個新的內核堆棧
? ? ? ? ?? ? ? ??(注意,是內核棧,不是用戶堆棧,用戶態(tài)的是復制的)
? ? ? ? ? ? ? (3)要修改復制過來的進程數(shù)據(jù),比如pid、進程鏈表等等都要改改吧,見copy_process內部。
4、從用戶態(tài)的代碼看fork()----子進程從哪里開始執(zhí)行?
函數(shù)返回了兩次,即在父子進程中各返回一次,父進程從系統(tǒng)調用中返回比較容易理解,子進程從系統(tǒng)調用中返回,那它在系統(tǒng)調用處理過程中的哪里開始執(zhí)行的呢?這就涉及子進程的內核堆棧數(shù)據(jù)狀態(tài)和task_struct中thread記錄的sp和ip的一致性問題,這是在哪里設定的?copy_thread in copy_process
*childregs = *current_pt_regs(); //復制內核堆棧 childregs->ax = 0; //為什么子進程的fork返回0,這里就是原因! p->thread.sp = (unsigned long) childregs; //調度到子進程時的內核棧頂 p->thread.ip = (unsigned long) ret_from_fork; //調度到子進程時的第一條指令地址?
轉載于:https://www.cnblogs.com/huangfuyuan/p/9785142.html
《新程序員》:云原生和全面數(shù)字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Linux fork()一个进程内核态的变化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 7-1 银行业务队列简单模拟 (25 分
- 下一篇: codeblock 恢复默认字体设置