您的当前位置:首页正文

waitpid函数源码

2024-11-07 来源:个人技术集锦
int  sys_waitpid ( pid_t  pid , unsigned   long   *  stat_addr ,   int  options ) //挂起当前进程,直到pid指定的子进程退出终止或者收到要求终止该进程 的信号 ,或者需要调用 一个信号处理函数

{
     int  flag ,  code ;
     struct  task_struct  * *  p ;

    verify_area ( stat_addr , 4 ) ; //验证区域大小是否可用

repeat :
    flag = 0 ;
     for ( =   & LAST_TASK  ;  p  >   & FIRST_TASK  ;   - - p )   {
         if   ( ! * | |   * = =  current ) //空项,本进程项跳过

             continue ;
         if   ( ( * p ) - > father  ! =  current - > pid ) //不是当前进程的子进程跳过,

             continue ;
         //以下的语名定为当前进程 的子进程 

         if   ( pid > 0 )   { //pid>0,等待指定的进程pid 

             if   ( ( * p ) - > pid  ! =  pid ) //不是当前要找的子进程,跳过

                 continue ;
         }   else   if   ( ! pid )   { //pid==0    等待进程组号等于当前进程组号的任何子进程

             if   ( ( * p ) - > pgrp  ! =  current - > pgrp ) //扫描 的进程组号与当前的进程组号不相等,跳过

                 continue ;
         }   else   if   ( pid  ! =   - 1 )   { // pid<-1等待指定进程pid 绝对值的进程

             if   ( ( * p ) - > pgrp  ! =   - pid ) //不是当前要找的子进程,跳过

                 continue ;
         }
         //以下的语名定为要找到的进程

         switch   ( ( * p ) - > state )   {
             case  TASK_STOPPED : //子进程非正常结束

                 if   ( ! ( options  &  WUNTRACED ) ) //参数 option 可以为 0 或WNOHANG(如果没有任何已经结束的子进程则马上返回, 不予以等待)或 WUNTRACED (如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会),如果WUNTRACED没有置位,无需产即返回,可继续扫描其他进程

                     continue ;
                put_fs_long ( 0x7f , stat_addr ) ; //如果WUNTRACED置位,则写入状态信息,返回此子进程 号

                 return   ( * p ) - > pid ;
             case  TASK_ZOMBIE : //子进程非正常结束

                current - > cutime  + =   ( * p ) - > utime ; //用户态运行时间累计到当前进程(父进程中)

                current - > cstime  + =   ( * p ) - > stime ; //系统态运行时间累计到当前进程(父进程中)

                flag  =   ( * p ) - > pid ;      //取子进程号

                code  =   ( * p ) - > exit_code ; //取子进程的退出码

                release ( * p ) ; //释放该子进程

                put_fs_long ( code , stat_addr ) ; //置状态信息为退出码值

                 return  flag ;
             default : //找到一个符合要求的子进程,它处于运行态或睡眠态,flag=1

                flag = 1 ;
                 continue ; //这个地方是否可以换成break 语名???

         }
     }
     if   ( flag )   {
         if   ( options  &  WNOHANG ) //如果options==WNOHANG(如果没有任何已经结束的子进程则马上返回, 不予以等待)时,则立即返回

             return  0 ;
        current - > state = TASK_INTERRUPTIBLE ; //置当前进程为可中断等待状态

        schedule ( ) ; //重新进程调度,重新调度后,当又轮到本程序进行时,则从下面的语句开始进行

         if   ( ! ( current - > signal   & =   ~ ( 1 < < ( SIGCHLD - 1 ) ) ) ) //如果本程序还没有收到子进程发过来的SIGCHLD信号,则重新开始查找

             goto  repeat ;
         else
             return   - EINTR ;
     }
     return   - ECHILD ;
}
//说明:LINE 190行的重新任务调度,是很有必要的,这样一任务调度,父进程就

//有可能暂时不运行,转让于子进程加以运行,这样就有可能子进程运行结束,

//当轮到父进程运行时,正好执行if (!(current->signal &= ~(1<<(SIGCHLD-1))))语句,

//也就是说能够收到子进程传过来的SIGCHLD信号,从而返回-EINTR(4),

//也就是等待到了子进程的结束
Top