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
- Linux内核0.11版本sys_waitpid()函数分析
- Linux内核0.11版本schedule()函数分析
- Linux内核0.11版本sched.c中sleep_on()函数分析
- linux内核schedule函数分析
- linux内核--wait_event_interruptible_timeout()函数分析
- linux 0.11 内核分析
- linux内核分析之signal.c函数
- Linux内核中mktime()函数算法分析
- Linux内核中start_kernel函数的分析
- Linux内核中mktime()函数算法分析
- linux内核启动第二阶段分析-setup_arch()函数
- linux内核calibrate_delay函数实现分析
- Linux-0.12内核sleep_on函数分析
- linux内核启动第二阶段分析-setup_arch()函数
- Linux内核---8.filechk函数分析
- linux内核中2410_gpio_cfgpin函数分析
- Netfilter分析 (Linux内核版本:2.4.21)
- Linux 2.6.36版本内核分析之schedule()
- phpize是什么
- 瞬时高并发(秒杀/活动)Redis方案
- 搞懂了这几点,你就学会了Web编程
- 安装 arm-linux-gdb7.5 & 可能出现的两类问题解决
- 在linux下创建一个可运行shell脚本
- Linux内核0.11版本sys_waitpid()函数分析
- 内核模式代码签名走查(一)
- 大数据:Spark Storage(一) 集群下的区块管理
- 左旋转字符串
- golang set集合去重以及交叉并集计算
- python实现数据库迁移脚本
- Android 桌面图标右上角数字
- source insight 快捷键
- ==、=== 与equals和null