从以前就一个疑问就是当进程被加载到内存上之后,操作系统是如何对其进行管理的。今天我就对其进行一个总结。
首先再来明确一下进程和线程的概念,为什么要说到线程呢?因为从Linux内核的角度出发是没有线程的,把线程是当作进程对待的。并没有为其专门的去设计调度算法和数据结构。所以Linux和windows等一些操作系统对于线程的实现有着比较大的区别,拿windows举例,其内核中提供了专门支持线程的机制,对于它们而言线程就是“轻量级的进程”,光从叫法上就和Linux上的线程做了区分。
进程:正在执行的可执行文件,加载到内存上的指令和数据,还有打开的文件、地址空间、挂起的信号等等资源的集合,正在执行的程序代码的活标本。
线程:进程内部的一条执行路径(执行序列)。又可称为进程中的活动对象。(这里书上是这么讲的,每个线程都拥有一个独立的程序计数器、进程栈和一组进程寄存器。内核调度的对象是线程,而不是进程。说实话我在理解这句话时费了很大的劲,一方面感觉很矛盾,一方面有感觉好像对着呢。下面我就按着我的理解解释一下这句话。)每个线程都有一个独立的程序计数器、线程栈和一组线程寄存器(这里是站在一个进程有多个线程的角度上的,而理解书上之所以那么说是因为站在了一个进程只有一个线程的角度上,因为在传统的Unix系统上一个进程只包含一个线程),内核调度的对象是活动的序列,而不是进程,因为进程可以有很多个活动的序列,调度切换的也是序列。(在Linux上虽然没有真正意义上的线程(确确实实实现的轻量级进程),但调度的对象确实是线程,因为这里的线程指的是活动序列,此线程非彼线程,可能有点绕,理解一下。)
搞清楚这些后,就进入今天的正题。
一、Linux对于进程的管理
1.进程在内核中的存在形式
对于Linux而言进程其实就是一个Struct,一堆进程就是一张结点数值为Struct的双向循环链表,这个Struct在内核叫做task_struct 进程描述符的结构,它上面存储了关于一个进程的所有信息,在32位机器上大约有1.7K,包含了进程所打开的文件、进程的地址空间、挂起的信号、进程的状态等等。