shell的原理,说来简单,其实就是用一个子进程来执行一个命令。
一个新的进程需要的要素有:
自己的代码,数据和堆栈;
在proc_table[ ]中占用一个位置;
在GDT中占用一个位置,用以存放进程对应的LDT描述符。
后两项工作比较容易完成,那第一项呢,代码、数据和堆栈从哪里来呢?传统上,生成一个新的进程时,这些都是直接从某个已有的进程那里继承或者复制。这也正解释了子进程这一概念:如果新的进程C的代码、数据和堆栈是从已有的进程P而来,那么P被称为父进程(parent),C被称为子进程(child)。也就是父子进程是同一个程序代码,通过if--else进入不同分支执行。
生成一个子进程的系统调用被称为fork(),操作系统接到一个fork请求后,会将调用者复制一份,这时就会有两个一模一样的进程同时运行。fork()的返回值有两种:零或非零。如果返回零,表明自己是个子进程;如果返回非零,不仅表明自己是父进程,而且返回值即子进程的pid。还有一个方法,可以让进程得知自己是父进程还是子进程,那就是通过调用getpid()。每个进程有唯一的pid,如果调用fork()前后pid一致,说明进程为父进程,反之为子进程。