Linux下的進程管理——task_struct

  我們都曉得所謂的進程就是正在運行的一個程序,它是由正文段,用戶數據段和系統數據段所組成的一個動態實體。系統數據段存放着進程的控制信息。其中包括進程控制塊PCB。

  而在linux中每一個進程都由task_struct數據結構來定義(也稱爲任務結構體)。task_struct就是我們通常所說的PCB。它是進程存在的唯一標識,也是Linux進程實體的核心。

  當我們調用fork()時,系統會爲我們產生一個task_struct結構,然後從父進程,那裏繼承一些數據, 並把新的進程插入到進程樹中,以待進行進程管理。因此task_struct的結構對於我們理解進程調度有着關鍵作用。

在進行剖析task_struct的定義之前.我們先看一下一個進程基本的要求有哪些:

1,進程狀態,將紀錄進程在等待,運行,或死鎖   

2,調度信息,由哪個調度函數調度,怎樣調度等   

3,進程的通訊狀況   

4,因爲要插入進程樹,必須有聯繫父子兄弟的指針,當然是task_struct型   

5,時間信息,比如計算好執行的時間,以便cpu分配   

6,標號,決定改進程歸屬   

7,可以讀寫打開的一些文件信息   

8,進程上下文和內核上下文   

9,處理器上下文   

10,內存信息   

只有這些結構存在了,才能滿足一個進程的所有要求.

然後我們打開/include/linux/sched.h 

找到task_struct的定義:   
struct task_struct  {   

  /* these are hardcoded - don't touch */這裏是一些硬件設置對程序原來說是透明的.

其中state說明了該進程是否可以執行,還是可以中斷等信息.

Flage是進程號,在調用fork()時給出,

addr_limit是區分內核進程與普通進程在內存存放的位置不同  

  volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */  

  unsigned long flags;   /* per process flags, defined below   */   

  int  sigpending; 

  mm_segment_t  addr_limit; /* thread address space: 0-0xBFFFFFFF  for user-thead                                         0-0xFFFFFFFF  for kernelthread */

  struct exec_domain *exec_domain;  

  long   need_resched;     
/*   various   fields   */   

  count是計數器   priorrity是優先級  

  long   counter;  

  long   priority;  

  cycles_t   avg_slice;  

/*   SMP   and   runqueue   state   */   爲多處理機定義的變量.  

  int   has_cpu;  

  int   processor;  

  int   last_processor;  

  int   lock_depth;   /*   Lock   depth.   We   can   context   switch   in   and   out   of   holding   a   syscall   kernel   lock...   */  

 爲了在進程樹中排序,   定義的父子,兄弟指針  

  struct   task_struct   *next_task,   *prev_task;  

  struct   task_struct   *next_run,   *prev_run;     
/*   task   state   */   定義task運行的狀態,以及信號  

  struct   linux_binfmt   *binfmt;  

  int   exit_code,   exit_signal;  

  int   pdeath_signal;   /*   The   signal   sent   when the parent dies   */   

/* 定義可進程的用戶號,用戶組以及進程組*/  

  unsigned   long   personality;  

  int   dumpable:1;  

  int   did_exec:1;  

  pid_t   pid;  

  pid_t   pgrp;  

  pid_t   tty_old_pgrp;  

  pid_t   session;  

/*   boolean   value   for   session   group   leader   */  

 是不是進程組的頭文件  

  int   leader;  

/*  

*   pointers   to   (original)   parent   process,   youngest   child,   younger   sibling,  

*   older   sibling,   respectively.   (p->father   can   be   replaced   with   *   p->p_pptr->pid)  

*/  

  父子進程的一些指針  

  struct   task_struct   *p_opptr,   *p_pptr,   *p_cptr,   *p_ysptr,   *p_osptr;     
/*   PID   hash   table   linkage.   */   在調度中用的一些hash表  

  struct   task_struct   *pidhash_next;  

  struct   task_struct   **pidhash_pprev;     
/*   Pointer   to   task[]   array   linkage.   */  

  struct   task_struct   **tarray_ptr;     
  struct   wait_queue   *wait_chldexit;   /*   for   wait4()   等待隊列   */       struct   semaphore   *vfork_sem;   /*   for   vfork()   */  

  unsigned   long   policy,   rt_priority;  

  unsigned   long   it_real_value,   it_prof_value,   it_virt_value;  

  進程的性質因爲實時進程與普通進程的調度算法不一樣所以應有變量區分  

下面是進程的一些時間信息  

  unsigned   long   it_real_incr,   it_prof_incr,   it_virt_incr;  

  struct   timer_list   real_timer;  

  struct   tms   times;  

  unsigned   long   start_time;  

  long   per_cpu_utime[NR_CPUS],   per_cpu_stime[NR_CPUS];定義了時間片的大小  

/*   mm   fault   and   swap   info:   this   can   arguably   be   seen   as   either   mm-specific   or   thread-specific   */  

  內存信息  

  unsigned   long   min_flt,   maj_flt,   nswap,   cmin_flt,   cmaj_flt,   cnswap;   int   swappable:1;  

/*   process   credentials   */  

  uid_t   uid,euid,suid,fsuid;  

  gid_t   gid,egid,sgid,fsgid;  

  int   ngroups;  

  gid_t   groups[NGROUPS];  

  kernel_cap_t   cap_effective,   cap_inheritable,   cap_permitted;  

  struct   user_struct   *user;  

以下英文註釋很清楚  

/*   limits   */  

  struct   rlimit   rlim[RLIM_NLIMITS];  

  unsigned   short   used_math;  

  char   comm[16];   /*   file   system   info   */  

  int   link_count;  

  struct   tty_struct   *tty;   /*   NULL   if   no   tty   */  

/*   ipc   stuff   */     
  struct   sem_undo   *semundo;  

  struct   sem_queue   *semsleeping;  

/*   tss   for   this   task   */  

  struct   thread_struct   tss;  

/*   filesystem   information   */  

  struct   fs_struct   *fs;  

/*   open   file   information   */  

  struct   files_struct   *files;  

/*   memory   management   info   */  

  struct   mm_struct   *mm;     
/*   signal   handlers   */  

  spinlock_t   sigmask_lock;  

/*   Protects   signal   and   blocked   */  

  struct   signal_struct   *sig;   sigset_t   signal,   blocked;  

  struct   signal_queue   *sigqueue,   **sigqueue_tail;  

  unsigned   long   sas_ss_sp;  

  size_t   sas_ss_size;  

};  

在分析完這個結構之後, 還有很多問題要想要問,也許不能完全理解,但基本的框架要有.要有一個大體的認識,要瞭解到一個task_struct中基本的結構,這對今後學習進程和線程有着舉足輕重的作用。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章