linux 進程管理與調度(一)

進程結構 linux

  進程在內核的源代碼中以結構體表示,篇幅很長,在此列舉一小段關鍵代碼,能夠發現是個雙向鏈表,具體的能夠在內核目錄下找一個叫「sched.h」的頭文件。緩存

struct task_struct {
      struct task_struct *real_parent; /* real parent process */
      struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */
      /*
       * children/sibling forms the list of my natural children
       */
      struct list_head children;      /* list of my children */
      struct list_head sibling;       /* linkage in my parent's children list */
      struct task_struct *group_leader;       /* threadgroup leader */ 

      ……
};

  進程被存放在叫作任務鏈表(tasklist)的雙向循環鏈表中,linux經過slab分配器分配task_struct結構,這樣能達到對象複用和緩存着色(cache coloring)的目的。函數

  結構體中主要由四部分組成spa

  1.進程控制塊:進程標誌線程

  2.進程程序塊:可與其餘程序共享code

  3.進程數據塊:進程專屬空間,用於存放各類私有數據以及堆棧空間orm

  4.獨立的空間:線程對象

進程狀態blog

#define TASK_RUNNING            0
#define TASK_INTERRUPTIBLE      1
#define TASK_UNINTERRUPTIBLE    2
#define __TASK_STOPPED          4
#define __TASK_TRACED           8
/* in tsk->exit_state */
#define EXIT_ZOMBIE             16
#define EXIT_DEAD               32
/* in tsk->state again */
#define TASK_DEAD               64
#define TASK_WAKEKILL           128
#define TASK_WAKING             256

 

 

進程的狀態一共有五種。隊列

1.TASK_RUNNING(運行)--------進程正在執行,或者在隊列中等待執行。這是進程在用戶空間中惟一可能的狀態,也能夠應用到內核空間中正在執行的進程。
2.TASK_INTERRUPTIBLE(可中斷)--------進程正在睡眠(也就是他被阻塞)等待某些條件達成。一旦這些條件達成,內核就會把進程狀態設置爲運行,處於此狀態的進程也會由於收到信號而提早被喚醒並投入運行。
3.TASK_UNINTERRUPTIBALE(不可中斷)--------除了會由於接收到信號而被喚醒從而投入運行外,這個狀態與可打斷狀態相同。這個狀態一般在進程必須等待時不受干擾或事件很快就會發生時出現。因爲處於此狀態的任務對信號不做響應,因此較之可中斷狀態,用的較少。
4.TASK_ZOMBIE(僵死)-------該進程已經結束了,但父進程尚未調用wait()系統調用。一旦父進程調用了wait(),進程描述符就會被釋放。
5.TASK_STOPPED(中止)---------進程中止執行,進程沒有投入運行也不能投入運行。
 

 

QQ截圖20151127164758

 

 

進程的建立

 

  在linux系統中,全部進程都是PID爲1的init進程的後代。內核在系統啓動的最後階段啓動init進程。該進程讀取系統的初始化腳本,並執行其餘的相關程序,最終完成系統啓動的整個進程。

image

image 

 

 

 

  進程是系統中基本的執行單位(線程是最小的調度單位),能夠利用fork函數建立一個新的進程;

pid_t fork( void )

  fork() 函數不須要參數,但返回兩次,返回值有三種狀況:

(1)對於父進程,fork函數返回新的子進程的ID。

(2)對於子進程,fork函數返回0。

(3)若是出錯,fork函數返回-1。

 

   fork函數建立一個新的進程,並從內核中爲此進程獲得一個新的可用進程ID,以後爲這個新進程分配進程空間,並將父進程的進程空間中的內容複製到子進程的進程空間中,包括父進程的數據段+堆棧段,並與父進程共享代碼段。

 

fork函數以後,子進程從等待fork返回開始執行,而不是從頭開始。

  •   注意:子進程徹底複製了父進程的地址空間的內容,包括堆棧段+數據段的內容。可是,子進程並無複製代碼段,而是和父進程共享代碼段。代碼段是隻讀的,不存在修改的問題,所以能夠共用。在建立一個子進程後,子進程的地址空間徹底和父進程分開,父子進程是兩個獨立的進程。

     

     

      linux環境下提供一個和fork函數相似的函數,能夠用來建立一個共用父進程地址空間的子進程。

    pid_t  vfork();

    vfork()與fork()的區別:

    (1)vfork產生的子進程和父進程徹底共享地址空間,包括代碼段+數據段+堆棧段。子進程對共享資源進行的修改,也會影響到父進程。

    (2)vfork函數產生的子進程必定比父進程先運行。即父進程調用了vfork函數後會等待子進程運行後再運行。

  • 相關文章
    相關標籤/搜索