加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_镇江站长网 (https://www.0511zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux进程管理之wait系统调用

发布时间:2016-02-07 21:19:44 所属栏目:Linux 来源:网络整理
导读:六: wait4 ()系统调用 在父进程中,用wait4()可以获得子进程的退出状态,并且防止在父进程退出前,子进程退出造成僵死 状态。这是我们这节分析的最后一个小节了

对TASK_TRACED和TASK_STOPPED状态的子进程操作是在wait_task_stopped()中完成的。它的代码如下:

static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
          int noreap, struct siginfo __user *infop,
          int __user *stat_addr, struct rusage __user *ru)
{
   int retval, exit_code;
   //进程退出状态码为零.没有相关退出信息
   if (!p->exit_code)
     return 0;
   //
   if (delayed_group_leader && !(p->ptrace & PT_PTRACED) &&
     p->signal && p->signal->group_stop_count > 0)
     return 0;
   //正在取task里面的信息,为了防止意外释放,先增加它的引用计数
   get_task_struct(p);
   read_unlock(&tasklist_lock);
   //如果WNOWAIT 被定义
   if (unlikely(noreap)) {
     pid_t pid = p->pid;
     uid_t uid = p->uid;
     int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
     exit_code = p->exit_code;
     //退出状态码为零,但是过程已经处于退出状态中(僵尸或者是死进程)
     if (unlikely(!exit_code) || unlikely(p->exit_state))
       goto bail_ref;
     //把子进程的各项信息保存起来
     //返回值是退出子进程的PID
     return wait_noreap_copyout(p, pid, uid,
              why, exit_code,
              infop, ru);
   }
   write_lock_irq(&tasklist_lock);
   //如果子进程没有退出.只要取子进程的退出信息,再清除子进程的退出信息
   //即可
   exit_code = xchg(&p->exit_code, 0);
   if (unlikely(p->exit_state)) {
     p->exit_code = exit_code;
     exit_code = 0;
   }
   if (unlikely(exit_code == 0)) {
      write_unlock_irq(&tasklist_lock);
bail_ref:
     put_task_struct(p);
     return -EAGAIN;
   }
   //将子进程加到父进程子链表的末尾
   remove_parent(p);
   add_parent(p);
   write_unlock_irq(&tasklist_lock);
   //收集相关的信息
   retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
   if (!retval && stat_addr)
     retval = put_user((exit_code << 8) | 0x7f, stat_addr);
   if (!retval && infop)
     retval = put_user(SIGCHLD, &infop->si_signo);
   if (!retval && infop)
     retval = put_user(0, &infop->si_errno);
   if (!retval && infop)
     retval = put_user((short)((p->ptrace & PT_PTRACED)
             ? CLD_TRAPPED : CLD_STOPPED),
           &infop->si_code);
   if (!retval && infop)
     retval = put_user(exit_code, &infop->si_status);
   if (!retval && infop)
     retval = put_user(p->pid, &infop->si_pid);
   if (!retval && infop)
     retval = put_user(p->uid, &infop->si_uid);
   if (!retval)
     retval = p->pid;
   //减少task的引用计数
   put_task_struct(p);
   BUG_ON(!retval);
   return retval;
}

(编辑:应用网_镇江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!