第六週: 進程的描述和進程的建立

呂鬆鴻 + 原創做品轉載請註明出處 + 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000數據結構

1、進程的描述

1.操做系統三大功能:

進程管理
內存管理
文件系統

2.進程描述符task_struct數據結構

task _ struct:爲了管理進程,內核必須對每一個進程進行清晰的描述,進程描述符提供了內核所需瞭解的進程信息。

進程的狀態:Linux進程的狀態(就緒態、運行態、阻塞態)

進程的標示pid:用來標示進程

3.Linux進程的狀態

4.進程描述符task_struct數據結構:

struct task_struct {
volatile long state;    /* 進程的運行狀態-1 unrunnable, 0 runnable, >0 stopped */
void *stack;    /*指定了進程的內核堆棧*/
atomic_t usage;
unsigned int flags; /* 每個進程的標識符 */
int on_rq;  /*運行隊列*/
pid_t pid; /*進程標識符*/
struck list_head task;  /*進程鏈表*/
/*父子進程*/
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; 
struct list_head children;    /* list of my children */

2、進程的建立

建立進程的系統調用有3個,它們經過統一的系統調用接口進入核心態運行後就分道揚鑣,各自調用本身的內核函數sys_fork、sys_clone、sys_vfork進行處理。這三個函數最終都是調用do_fork函數進行建立子進程的工做,只不過使用的參數有所不一樣。
Linux經過複製父進程來建立一個新進程:複製父進程PCB--task_struct來建立一個新進程,要給新進程分配一個新的內核堆棧。
修改複製過來的進程數據,好比pid、進程鏈表等等執行copy_process和copy_thread。
以後,從ret_from_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");
    }
}

3、實驗內容

1.刪除menu,下載新代碼並執行。

2.gdb調試

3.設置斷點

4.單步追蹤

4、總結

Linux經過複製父進程來建立一個新進程:複製父進程PCB--task_struct來建立一個新進程,要給新進程分配一個新的內核堆棧。

修改複製過來的進程數據,好比pid、進程鏈表等等執行copy_process和copy_thread。

設置sp調度到子進程時的內核棧頂,ip轉到子進程時的第一條指令地址

以後,當子進程得到CPU的控制權開始運行的時候,ret _ form _ fork能夠將後面的堆棧出棧,從iret返回到用戶態,從而切換到子進程的用戶空間,完成新進程的建立。
相關文章
相關標籤/搜索