进程退出和等待进程

当进程执行完它的工作后,就需要执行退出操作,释放进程占用的资源。ucore 分了两步来完成这个工作,首先由进程本身完成大部分资源的占用内存回收工作,然后由此进程的父进程完成剩余资源占用内存的回收工作。为何不让进程本身完成所有的资源回收工作呢?这是因为进程要执行回收操作,就表明此进程还存在,还在执行指令,这就需要内核栈的空间不能释放,且表示进程存在的进程控制块不能释放。所以需要父进程来帮忙释放子进程无法完成的这两个资源回收工作。

为此在用户态的函数库中提供了 exit 函数,此函数最终访问 sys_exit 系统调用接口让操作系统来帮助当前进程执行退出过程中的部分资源回收。我们来看看 ucore 是如何做进程退出工作的。

首先,exit 函数会把一个退出码 error_code 传递给 ucore,ucore 通过执行内核函数 do_exit 来完成对当前进程的退出处理,主要工作简单地说就是回收当前进程所占的大部分内存资源,并通知父进程完成最后的回收工作,具体流程如下:

1. 如果 current->mm != NULL,表示是用户进程,则开始回收此用户进程所占用的用户态虚拟内存空间;

a) 首先执行“lcr3(boot_cr3)”,切换到内核态的页表上,这样当前用户进程目前只能在内核虚拟地址空间执行了,这是为了确保后续释放用户态内存和进程页表的工作能够正常执行;

b) 如果当前进程控制块的成员变量 mm 的成员变量 mm_count 减 1 后为 0(表明这个 mm 没有再被其他进程共享,可以彻底释放进程所占的用户虚拟空间了。),则开始回收用户进程所占的内存资源:

i. 调用 exit_mmap 函数释放 current->mm->vma 链表中每个 vma 描述的进程合法空间中实际分配的内存,然后把对应的页表项内容清空,最后还把页表所占用的空间释放并把对应的页目录表项清空;

ii. 调用 put_pgdir 函数释放当前进程的页目录所占的内存;

iii. 调用 mm_destroy 函数释放 mm 中的 vma 所占内存,最后释放 mm 所占内存;

c) 此时设置 current->mm 为 NULL,表示与当前进程相关的用户虚拟内存空间和对应的内存管理成员变量所占的内核虚拟内存空间已经回收完毕;

2. 这时,设置当前进程的执行状态 current->state=PROC_ZOMBIE,当前进程的退出码 current->exit_code=error_code。此时当前进程已经不能被调度了,需要此进程的父进程来做最后的回收工作(即回收描述此进程的内核栈和进程控制块);

3. 如果当前进程的父进程 current->parent 处于等待子进程状态:

current->parent->wait_state==WT_CHILD,

则唤醒父进程(即执行“wakup_proc(current->parent)”),让父进程帮助自己完成最后的资源回收;

4. 如果当前进程还有子进程,则需要把这些子进程的父进程指针设置为内核线程 initproc,且各个子进程指针需要插入到 initproc 的子进程链表中。如果某个子进程的执行状态是 PROC_ZOMBIE,则需要唤醒 initproc 来完成对此子进程的最后回收工作。

5. 执行 schedule()函数,选择新的进程执行。

那么父进程如何完成对子进程的最后回收工作呢?这要求父进程要执行 wait 用户函数或 wait_pid 用户函数,这两个函数的区别是,wait 函数等待任意子进程的结束通知,而 wait_pid 函数等待进程 id 号为 pid 的子进程结束通知。这两个函数最终访问 sys_wait 系统调用接口让 ucore 来完成对子进程的最后回收工作,即回收子进程的内核栈和进程控制块所占内存空间,具体流程如下:

1. 如果 pid!=0,表示只找一个进程 id 号为 pid 的退出状态的子进程,否则找任意一个处于退出状态的子进程;

2. 如果此子进程的执行状态不为 PROC_ZOMBIE,表明此子进程还没有退出,则当前进程只好设置自己的执行状态为 PROC_SLEEPING,睡眠原因为 WT_CHILD(即等待子进程退出),调用 schedule()函数选择新的进程执行,自己睡眠等待,如果被唤醒,则重复跳回步骤 1 处执行;

3. 如果此子进程的执行状态为 PROC_ZOMBIE,表明此子进程处于退出状态,需要当前进程(即子进程的父进程)完成对子进程的最终回收工作,即首先把子进程控制块从两个进程队列 proc_list 和 hash_list 中删除,并释放子进程的内核堆栈和进程控制块。自此,子进程才彻底地结束了它的执行过程,消除了它所占用的所有资源。

results matching ""

    No results matching ""