我们在使用linux系统时经常会使用系统命令ps命令来查看系统进程。如下几张截图分别是ubuntu桌面系统和某个嵌入式设备linux系统中使用ps命令获取的部分系统进程。
在下面截图中我们可以看到第一列为UID,即当前进程是由哪个用户创建的;
第二列PID,是当前进程ID;
第三列PPID是当前进程的父进程,即当前进程是由哪个进程创建;
最后一列CMD是创建当前进程的命令。
在截图中我们可以看到,进程号为1和2的两个进程在ubuntu系统中和嵌入式系统中都是一样的,且两个进程的父进程都是0。
那么linux系统下的这些进程是怎么启动的呢?
下面就给大家做个简单介绍大概过程。




从截图中我们可以看到,1号和2号进程的父进程都是0号进程,其他进程的父进程大多是1号或2号进程,部分进程的PPID是其他进程的PID,但往上找他的父进程最终能找到1号进程。那么这些进程是如何创建的呢?
0号进程
首先看下0号进程,通常我们把0号进程称为idle进程,或者叫swapper进程,这是因为在内核代码中0号进程的comm字段被静态赋值成了swapper,如下截图。他是linux系统启动的第一个进程,也是唯一一个不需要通过fork或kernel_thread创建的进程。在嵌入式设备中,uboot引导kernel启动后,在kernel内调用start_kernel函数对嵌入式系统进行如时钟、CPU架构、内存管理等进行初始化后,调用rest_init函数,从此0号进程的生涯便开始了。


1号和2号进程
0号进程启动后,在rest_init函数中,0号进程会调用kernel_thread(kernel_init, NULL, CLONE_FS|CLONE_SIGHAND)和kernel_thread(kthreadd, NULL, CLONE_FS|CLONE_SIGHAND)来创建1号和2号进程。从上面代码中可以看到,1号进程为init进程,这也是第一个真正意义上的进程,他会完成剩余的初始化工作,并启动其他系统进程,在上面截图中可以看到大多数进程的PPID都是1。所以,1号进程是所有系统进程的祖先。
在1号进程创建后,rest_init会接着创建2号进程。他的任务就是管理和调度其他内核线程kernel_thread,从上面截图中可以看到,除2号进程外,所有启动命令用[]括起来的线程的父进程都是2号进程。
0号进程的归宿
0号进程在启动完1号和2号进程后最终去了哪,他还在干什么工作?0号进程在做完上面工作后会调用cpu_idle函数演变成了idle进程,idle在系统没有其他就绪的进程可执行时会被调度。1号和2号进程
0号进程启动后,在rest_init函数中,0号进程会调用kernel_thread(kernel_init, NULL, CLONE_FS|CLONE_SIGHAND)和kernel_thread(kthreadd, NULL, CLONE_FS|CLONE_SIGHAND)来创建1号和2号进程。从上面代码中可以看到,1号进程为init进程,这也是第一个真正意义上的进程,他会完成剩余的初始化工作,并启动其他系统进程,在上面截图中可以看到大多数进程的PPID都是1。所以,1号进程是所有系统进程的祖先。
在1号进程创建后,rest_init会接着创建2号进程。他的任务就是管理和调度其他内核线程kernel_thread,从上面截图中可以看到,除2号进程外,所有启动命令用[]括起来的线程的父进程都是2号进程。
结尾
linux进程启动扫盲式的介绍这些,很多细节性东西一时半会请不完,如1号进程是内核创建的,怎么就成了用户太进程了,0号进程idle在做什么等,后续再结合具体代码找台设备精讲下。
转载请注明:XAMPP中文组官网 » linux进程启动-扫盲版