fork(),clone()系统调用进行进程创建的过程

首先它们最终都调用了内核里的do_fork()函数,然后完成了下述操作

1、调用alloc_task_struct()函数申请8KB的内核栈内存空间,供新建进程使用;

2、让指针指向父进程的PCB,然后将父进程的PCB内容拷贝到给新进程分配的PCB中去,此时父子进程完全相同,当然拷贝内容包括了:指令,变量值,程序调用栈,缓存区,环境变量等等,而此时若搭配一些有缓存的语句,就会出现意想不到的结果了,这是后话。

3、检查创建该进程后,是否越界,即该用户所拥有的进程数目是否超过了给它分配的资源的限制;

4、然后就是建立新创建的子进程的新的,独有资源,并且通知内核此进程已经诞生。

5、设置子进程的状态,确保它不会马上投入运行;

6、调用get_pid()为新子进程获取一个有效的PID;

7、进一步更新从父进程PCB继承来的其他所有不同地方,例如亲属关系,状态信息等;

8、根据传递给clone()的参数标志,拷贝或共享打开的文件,文件系统信息,信号处理函数,进程的虚拟地址空间等。若进程包含线程,则所有线程共享这些资源,否则各进程对这些资源进行拷贝;

9、把新的PCB插入到进程链表,确保进程间的亲属关系;

10、把新的PCB插入到pidhash哈希表;

11、把子进程的状态设置为TASK_RUNNING,并调用weak_up_process()把子进程插入到运行队列中;

12、让父子进程平分剩余时间片;

13、返回子进程PID,并由用户态下的父进程读取。

注意:子进程已经就绪,但还得看调度程序什么时候将CPU交给它,它才能真正开始运行。

同时,操作系统内核会有意地选择让子进程先执行,然后才是父进程。这是因为一般子进程会立即调用exec()以读取可执行文件并将其载入进程地址空间开始运行,来避免写时复制的额外开销。

posted @ 2013-07-24 15:29  herry_tu  阅读(1446)  评论(0编辑  收藏  举报