Chinaunix首页 | 论坛 | 博客
  • 博客访问: 122427
  • 博文数量: 41
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 306
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-01 10:41
文章分类

全部博文(41)

文章存档

2011年(1)

2009年(40)

我的朋友

分类:

2009-05-08 16:23:21

作者:sunmoon    
  在linux   中每一个进程都由task_struct   数据结构来定义.   task_struct就是我们通常所说的PCB.她是对进程控制的唯一手段也是最有效的手段.   当我们调用fork()   时,   系统会为我们产生一个task_struct结构.然后从父进程,那里继承一些数据,   并把新的进程插入到进程树中,   以待进行进程管理.因此了解task_struct的结构对于我们理解任务调度(在linux   中任务和进程是同一概念)的关键.在进行剖析task_struct的定义之前.   我们先按照我们的理论推一下它的结构.   1,   进程状态   ,将纪录进程在等待,运行,或死锁   2,   调度信息,   由哪个调度函数调度,怎样调度等   3,   进程的通讯状况   4,因为要插入进程树,必须有联系父子兄弟的指针,   当然是task_struct型   5,时间信息,   比如计算好执行的时间,   以便cpu   分配   6,标号   ,决定改进程归属   7,可以读写打开的一些文件信息   8,   进程上下文和内核上下文   9,处理器上下文   10,内存信息   因为每一个PCB都是这样的,   只有这些结构,   才能满足一个进程的所有要求.打开/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   kernel-thread   */  
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;  
};  
在分析完   这个结构之后,   还有很多问题要想,   也许不能读   但框架要搞好.需要向的问题有以下几个   1,在task_struct   中用的常量在那里定义呢,   如最大进程个数,   最多支持的cpu   个数,等等   2,在调用fork()   时,   系统是分配一块内存   会是这样么   malloc(1,sizeof(struct   task_struck))   拷贝一些变量,还是和父进程共用一部分内存.malloc   函数怎么实现(在内存管理那一部分,但此处我认为不能不想)   3,.对于线程来说,   又如何实现呢?   4,   调度策略函数schedule()有几种形势,   时间片轮转,   抢占式,优先级抢占式,   多级反馈制.除了时间片轮转外都要对进程树进行遍历,(对于实时进程的fifo机制不用)linux   是怎样保证了高效呢?如果把最大线成数修改,   效率会不会降低   5,   进程通讯用到的管道,信号结构如何
阅读(5758) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~