柯利南 2012-03-23
个人学习笔记,仅为加深记忆,水平有限,有错的地方,大家指正。
1、进程创建使用fork()
用户空间执行fork,陷入内核执行系统调用,创建子进程,实现父进程的拷贝,拷贝包括(进程控制块、页表)。父进程和子进程的页表共享物理页,没有实现内存的拷贝,linux采用了copy-on-write技术,就是子进程执行后如果有往内存写入的操作,操作系统就为子进程拷贝一份父进程内存的数据,父子进程的页表各自有自己的物理页相对应。
往往子进程创建以后都是通过exec执行另外的程序,此时释放从父进程复制过来的全部资源。这种情况就不需要拷贝父进程的大量数据了,cow技术避免了拷贝父进程的大量无用数据。
子进程创建完成后,返回2次,子进程返回0,父进程返回子进程的进程号(PID),PID存放在进程控制块(task_struct)中。返回后,父子进程各自执行任务。
我们还可以使用vfork()函数创建子进程,vfork()和fork()相比最大的好处是没有拷贝页表项.vfork()创建子进程后,父进程只能等待子进程终结或者执行另外程序后,父进程才能继续执行。
2、exit通常是子程序中用来终结程序的,调用后,进程终结。
exit内部机制是怎么运行的呢。
子程序exit代码在用户空间执行系统调用,系统调用陷入内核执行,操作系统释放进程控制块(PCB)中的资源,包括(页表项、文件描述符、信号量等),此时PCB还存在,然后设置returncode,发送SIGCLD信号给父进程,此时子进程的状态为ZOMBLE(僵死)。
父进程调用wait系统调用,陷入内核等待子进程发送的SIGCLD信号,接受到后,父进程取得子进程PCB中的errorcode,子进程运行的滴答数信息,然后wait调用返回。
子进程释放PCB资源,调度合适的进程执行(进程上下文切换),执行另一进程,此时子进程完全消亡。