进程在内核中的组织
进程和程序的区别
- 程序是可执行的代码以及执行时需要的数据等信息,存放在磁盘上的介质。
- 当程序被操作系统装载到内存并分配给它一定的资源后,此时可以称为进程。
- 程序是静态存储的概念,进程是动态加载以及执行的概念。
程序被加载到内存成为进程的流程:
程序被cpu载入到内存,然后利用fork创建进程;而后,cpu初始化进程、调度进程执行。
进程的组织形式——进程控制块
进程在内核中以 进程控制块(PCB) 的形式组织,进程控制块的信息如下图所示:
进程控制块task_struct结构
这里的结构,所用数据结构就是结构体。在C语言中,没有面向对象的概念,只有结构体的概念,所以,在操作系统中提到结构,所用的数据结构一般就是结构体。
进程控制块的结构英文名为task_stract,task_stract中存放着进程相关的信息:
- 进程id(pid)
- 用户id(uid)
- 有效用户id(euid)
- 进程状态(state)
- 进程退出状态(exit_state)
- 父进程指针/真正的父进程指针(结构体指针)等信息
除此之外,task_stract中还有文件系统管理、内存管理、通讯机制的相关信息:
- 进程与文件的关联(目录 struct fs_struct *fs)
- 进程对打开文件的组织(文件 struct files_struct *files)
- 内存管理(比如数据块和代码块,存放在磁盘不同的区域 struct mm_struct *mm)
- 进程间通信机制(struct signal_struct *signal / struct signalhand_struct *sighand)
进程还包含一些时间以及定时器、进程创建时间相关的信息:
作用(不太理解,大概就是记录进程执行时状态的时间记录):记录进程在用户态和和心态所经历的节拍数
- utime(用户态时间)
- stime(内核态时间)
- start_time / real_start_time(进程创建时间/进程真正创建时间)
其中real_start_time还包含了进程的睡眠时间
进程运行状态(五种状态)
五种状态分别是:就绪状态、两种等待状态、僵尸状态、结束状态
属性: volatile long state
取值:
- #define TASK_RUNNING 0
- #define TASK_INTERRUPTIBLE 1
- #define TASK_UNINTERRUPTIBLE 2
- #define TASK_ZOMBIE 3
- #define TASK_STOPPED 8
五种状态的详情叙述:
- 当进程被初始化创建之后,处于就绪状态;在操作系统对进程调度之后,给与相应的CPU资源(在资源的定义中:CPU调度、I/O操作、信号等都是系统的资源) 让其执行,此时进程应该处于运行态,但是在Linux中没有区分就绪态和运行态,而是统一称为TASK_RUNNING的状态(当TASK_RUNNING状态有时间片被调度的时候,就是所谓的运行态,反之为就绪态);
- 等待状态某资源(等待信号量)、或某事件(等待网络连接)的发生而被挂起的状态,这里又分为两种,一种是TASK_INTERRUPTIBLE,另一种是TASK_UNINTERRUPTIBLE,两者的重要区别在于是否能够响应异步信号(比如当某进程在使用硬件操作时不希望被打断,则其他进程会处在TASK_UNINTERRUPTIBLE状态);
- TASK_STOPPED,暂停状态,可以被恢复。
- TASK_ZOMBIE,Linux系统特有的一种状态,当进程的生命周期被终止而内核资源没有被释放,会处于TASK_ZOMBIE状态。
task_struct:文件管理、内存管理
介绍了进程中文件管理、内存管理 的组织形式,具体这里不详述。
参考学习视频
进程控制块的组织结构
- 物理组织结构
当多个进程存在时,系统设置了不同状态的队列,就绪队列、等待队列,对进程实现不同的调度。 - 逻辑组织结构
进程之间存在着相互关系(父子关系),如数据结构中的树结构,父进程创建子进程。如下图示是Linux系统当前运行的进程的结构:
由此可以看到Linux操作系统中进程的祖先进程是init进程。