code:exit - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki

Source

  • 进程自我终止

3212

3213 /* Release resources.

3214  * Save u. area for parent to look at.

3215  * Enter zombie state.

3216  * Wake up parent and init processes,

3217  * and dispose of children.

3218  */

3219 exit()

3220 {

3221     register int *q, a;

3222     register struct proc *p;

3223

3224     u.u_procp->p_flag =& ~STRC;

  • 去除当前进程的STRC标识,参看跟踪
3225     for(q = &u.u_signal[0]; q < &u.u_signal[NSIG];)

3226            *q++ = 1;

3227     for(q = &u.u_ofile[0]; q < &u.u_ofile[NOFILE]; q++)

3228           if(a = *q) {

3229                     *q = NULL;

3230                     closef(a);

3231           }

3232     iput(u.u_cdir);

  • 释放当前所在目录的内存inode
3233     xfree();
  • 释放共享正文段
3234     a = malloc(swapmap, 1);
  • 在盘交换区上分配大小为1块(512个字节)的空间,我们且称其为 残留信息块
3235     if(a == NULL)

3236           panic("out of swap");

  • 若分配失败,提示出错
3237     p = getblk(swapdev, a);

3238     bcopy(&u, p->b_addr, 256);

3239     bwrite(p);

  • 若分配成功,在内存中为 残留信息块 分配一缓存块p
  • 将进程图像中的USER结构以及其他一些内容读入p
    • 说明:此处意在保留USER结构的信息,其他的内容无所谓
  • 将缓存块p写回盘交换区的 残留信息块中
3240     q = u.u_procp;

3241     mfree(coremap, q->p_size, q->p_addr);

  • 释放内存中 进程图像站的内存空间
3242     q->p_addr = a;

3243     q->p_stat = SZOMB;

  • 将进程ppda区指针指向残留信息块
  • 置进程状态为SZOMB,此举是为了让父进程在调用wait函数时搜索自己终止的子进程时使用
3244

3245 loop:

3246     for(p = &proc[0]; p < &proc[NPROC]; p++)

3247     if(q->p_ppid == p->p_pid) {

3248          wakeup(&proc[1]);

3249          wakeup(p);

  • 寻找当前进程的父进程
    • 若能找到,唤醒父进程与1号进程
3250          for(p = &proc[0]; p < &proc[NPROC]; p++)

3251          if(q->p_pid == p->p_ppid) {

3252                p->p_ppid = 1;

3253                if (p->p_stat == SSTOP)

3254                         setrun(p);

  • 将当前进程的所有子进程的父进程置为1号进程,你可以把这个动作看作成是交代后事
  • 若子进程为SSTOP状态,则将其置为就绪态,交代跟踪的后事
3255          }

3256          swtch();

3257          /* no return */

3258     }

3259     q->p_ppid = 1;

3260     goto loop;

  • 若不能找到父进程,则强制将1#进程置为父进程,跳转至3245重新搜索
    • 搜索的结果肯定是搜到父进程为1号进程,然后再执行后续操作
3261 }

3262 /* ------------------------- */

Ref

Caller

⚠️ **GitHub.com Fallback** ⚠️