Linux内核0.11版本sys_waitpid()函数分析

来源:互联网 发布:阿里云服务器 mongodb 编辑:程序博客网 时间:2024/05/30 04:45
文章内容摘自与Linux内核完全注释(修正版v1.9.5)5.10.2部分系统调用waitpid()。挂起当前进程,直到pid 指定的子进程退出(终止)或者收到要求终止该进程的信号,或者是需要调用一个信号句柄(信号处理程序)。如果pid 所指的子进程早已退出(已成所谓的僵死进程),则本调用将立刻返回。子进程使用的所有资源将释放。如果pid > 0, 表示等待进程号等于pid 的子进程。如果pid = 0, 表示等待进程组号等于当前进程组号的任何子进程。如果pid < -1, 表示等待进程组号等于pid 绝对值的任何子进程。 [ 如果pid = -1, 表示等待任何子进程。]若options = WUNTRACED,表示如果子进程是停止的,也马上返回(无须跟踪)。 若options = WNOHANG,表示如果没有子进程退出或终止就马上返回。如果返回状态指针stat_addr 不为空,则就将状态信息保存到那里。142 int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)143 {144 int flag, code;145 struct task_struct ** p;147 verify_area(stat_addr,4);148 repeat:149 flag=0;// 从任务数组末端开始扫描所有任务,跳过空项、本进程项以及非当前进程的子进程项。150 for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) {151 if (!*p || *p == current) // 跳过空项和本进程项。152 continue;153 if ((*p)->father != current->pid) // 如果不是当前进程的子进程则跳过。154 continue;// 此时扫描选择到的进程p 肯定是当前进程的子进程。// 如果等待的子进程号pid>0,但与被扫描子进程p 的pid 不相等,说明它是当前进程另外的子进程,// 于是跳过该进程,接着扫描下一个进程。155 if (pid>0) {156 if ((*p)->pid != pid)157 continue;// 否则,如果指定等待进程的pid=0,表示正在等待进程组号等于当前进程组号的任何子进程。如果// 此时被扫描进程p 的进程组号与当前进程的组号不等,则跳过。158} else if (!pid) {159 if ((*p)->pgrp != current->pgrp)160 continue;// 否则,如果指定的pid<-1,表示正在等待进程组号等于pid 绝对值的任何子进程。如果此时被扫描// 进程p 的组号与pid 的绝对值不等,则跳过。161} else if (pid != -1) {162 if ((*p)->pgrp != -pid)163 continue;164}// 如果前3 个对pid 的判断都不符合,则表示当前进程正在等待其任何子进程,也即pid=-1 的情况。// 此时所选择到的进程p 正是所等待的子进程。接下来根据这个子进程p 所处的状态来处理。165 switch ((*p)->state) {// 子进程p 处于停止状态时,如果此时WUNTRACED 标志没有置位,表示程序无须立刻返回,于是继续// 扫描处理其它进程。如果WUNTRACED 置位,则把状态信息0x7f 放入*stat_addr,并立刻返回子进程// 号pid。这里0x7f 表示的返回状态使WIFSTOPPED()宏为真。参见include/sys/wait.h,14 行。166 case TASK_STOPPED:167 if (!(options & WUNTRACED))168 continue;169 put_fs_long(0x7f,stat_addr);170 return (*p)->pid;// 如果子进程p 处于僵死状态,则首先把它在用户态和内核态运行的时间分别累计到当前进程(父进程)// 中,然后取出子进程的pid 和退出码,并释放该子进程。最后返回子进程的退出码和pid。171 case TASK_ZOMBIE:172 current->cutime += (*p)->utime;173 current->cstime += (*p)->stime;174 flag = (*p)->pid; // 临时保存子进程pid。175 code = (*p)->exit_code; // 取子进程的退出码。176 release(*p); // 释放该子进程。177 put_fs_long(code,stat_addr); // 置状态信息为退出码值。178 return flag; // 退出,返回子进程的pid.// 如果这个子进程p 的状态既不是停止也不是僵死,那么就置flag=1。表示找到过一个符合要求的// 子进程,但是它处于运行态或睡眠态。179 default:180 flag=1;181 continue;182}183}// 在上面对任务数组扫描结束后,如果flag 被置位,说明有符合等待要求的子进程并没有处于退出// 或僵死状态。如果此时已设置WNOHANG 选项(表示若没有子进程处于退出或终止态就立刻返回),// 就立刻返回0,退出。否则把当前进程置为可中断等待状态并重新执行调度。184 if (flag) {185 if (options & WNOHANG) // 若options = WNOHANG,则立刻返回。186 return 0;187 current->state=TASK_INTERRUPTIBLE; // 置当前进程为可中断等待状态。188 schedule(); // 重新调度。// 当又开始执行本进程时,如果本进程没有收到除SIGCHLD 以外的信号,则还是重复处理。否则,// 返回出错码并退出。189 if (!(current->signal &= ~(1<<(SIGCHLD-1))))190 goto repeat;191 else192 return -EINTR; // 退出,返回出错码。193}// 若没有找到符合要求的子进程,则返回出错码。194 return -ECHILD;195 }

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 顺丰寄方客户要求退回快递费怎么办 蛋蛋被皮筋弹肿了怎么办 人肌肉里的绦虫卵怎么办 鞋子前面踢坏了怎么办 猫割完蛋蛋流东西怎么办 北京怡瑞被骗后怎么办 玩滑板睾丸碎了怎么办 雄鸽不会踩蛋怎么办 玩滑板蛋碎了怎么办 精子在精囊满了怎么办 孩子的睾丸一大一小怎么办 肾阳虚早射该怎么办 有奶水吸不出来怎么办 苹果mac商店里没有软件怎么办 战地1安装包损坏怎么办 战地4db显示数据异常怎么办 战地1亚服没人怎么办 战地一加载太慢怎么办 饥荒手机版怪物跟人就打狗包怎么办 电脑文件损坏开不了机怎么办 黑魂1武器损坏怎么办 系统注册表文件丢失或损坏怎么办 steam申诉填错信息怎么办 手机玩游戏老是闪退怎么办 美剧推荐不能看怎么办 最角两边有点烂怎么办 独显禁用了黑屏怎么办 目标文件夹访问被拒绝怎么办 苹果mac电脑很卡怎么办 未能成功安装设备驱动程序怎么办 mac更新系统卡住了怎么办 电脑卡住了文件没保存怎么办 迅雷卸载重装列表没了怎么办 多个dts文件音量不同怎么办 武装突袭3锁帧怎么办? 武装突袭3没子弹了怎么办 电脑系统注册表文件损坏怎么办 武装突袭3受伤了怎么办 模板跟旺铺版本不符合怎么办 cpu散热硅胶没了怎么办 武装突袭3掉帧怎么办