1.Linux 系统中创建新进程使用 fork() 系统调用。所有进程都是通过复制进程 0 而得到的,都是进程 0的子进程。
2.如果系统已经有 64 个进程在运行,则 fork() 系统调用会因为任务数组表中没有可用空项而出错返回。然后系统为新建进程在主内存区中申请一页内存来存放其任务数据结构信息,并复制当前进程任务数据结构中的所有内容作为新进程任务数据结构的模板。为了防止这个还未处理完成的新建进程被调度函数执行,此时应该立刻将新进程状态置为不可中断的等待状态(TASK_UNINTERRUPTIBLE )
3.随后对复制的任务数据结构进行修改。把当前进程设置为新进程的父进程,清除信号位图并复位新进程各统计值,并设置初始运行时间片值为 15 个系统滴答数( 150 毫秒)
4.接着根据当前进程设置任务状态段( TSS )中各寄存器的值。由于创建进程时新进程返回值应为 0 ,所以需要设置 tss.eax = 0 。
5.新建进程内核态堆栈指针 tss.esp0 被设置成新进程任务数据结构所在内存页面的顶端,而堆栈段 tss.ss0 被设置成内核数据段选择符。 tss.ldt 被设置为局部表描述符在 GDT 中的索引值。
6.如果当前进程使用了协处理器,把还需要把协处理器的完整状态保存到新进程的 tss.i387 结构中。
7.此后系统设置新任务的代码和数据段基址、限长并复制当前进程内存分页管理的页表。
8.如果父进程中有文件是打开的,则应将对应文件的打开次数增 1 。接着在 GDT 中设置新任务的 TSS 和 LDT 描述符项,其中基地址信息指向新进程任务结构中的 tss 和 ldt 。
9.最后再将新任务设置成可运行状态并返回新进程号。