进程、进程调度、进程状态、进程与程序、多任务

进程、进程调度、进程状态、进程与程序、多任务

多任务机制

  • 多任务处理是指用户可以在同一时间内运行多个应用程序,每个正在执行的应用程序被称为一个任务。Linux是一个支持多任务的操作系统,比起单任务系统它的功能增强了许多
  • 多任务操作系统使用某种调度策略支持多个任务并发执行。事实上(单核)处理器在某一时刻只能执行一个任务。每个任务创建时被分配时间片(几十到上百毫秒),任务执行(占用CPU)时,时间片递减。操作系统会在当前任务的时间片用完时调度执行其他任务。由于任务会频繁地切换执行,因此给用户多个任务同时运行的感觉。多任务操作系统通常有3个基本概念:任务、进程和线程
  • 任务指的是一个逻辑概念,指由一个软件完成的活动,或者是为实现某个目的而进行的一系列操作。通常一个任务是一个程序的一次运行,一个任务包含一个或多个完成独立功能的子任务,子任务是进程或线程。例如一个杀毒软件的一次运行是一个任务,目的是保护计算机系统不受各种病毒的侵害。这个任务包含多个独立功能的子任务,包括实时监控功能、定时查杀功能、防火墙功能等

进程与程序

  • 进程是指一个具有独立功能的程序在某个数据集合上的一次动态执行过程,它是操作系统进行资源分配和调度的基本单元。一次任务的运行可以激活多个进程,这些进程相互合作来完成该任务的一个最终目标
程序包含了一系列信息的文件,这些信息描述了程序在运行时如何创建一个进程,包括如下
  1. 二进制格式标识:每个程序文件都包含用于描述可执行文件格式的元信息
  2. 机器语言指令:对程序进行编码
  3. 程序入口地址:标识程序开始执行时的起始指令位置
  4. 数据:程序文件包含的变量初始值和程序使用的字面变量
  5. 符号表及重定位表:描述程序中函数和变量的位置及名称。这些表有多种用途,其中包含调试和运行时的符号解析
  6. 共享库和动态链接信息:程序文件所包含的一些字段,列出了程序运行时需要使用的共享库,以及加载共享库的动态链接器的路径名 7
进程是程序动态执行的过程,具有并发性、动态性、交互性和独立性
  • 并发性:指系统中多个进程可以同时并发执行,相互之间不受干扰
  • 动态性:指进程都有完整的生命周期,而且在进程中声明周期内,进程的状态是不断变化,而且进程具有动态的地址(包含代码、数据和进程控制块等)
  • 交互性:指进程是在执行过程中可能会与其他进程发生直接和间接的通信,如进程同步和进程互斥等,需要为此添加一定的进程处理机制
  • 独立性:指进程是一个相对完整的资源分配和调度的基本单位,各个进程的地址空间是相对独立的,因此需要引入一些通信机制起来实现进程之间的通信
进程和程序有本质区别
  1. 程序是一段静态的代码,是保存在非易失性存储器上的指令和数据的有序集合,没有任何执行的概念
  2. 进程是一个动态的概念,它是程序的一次执行过程,包括了动态创建、调度、执行和消亡的整个过程,它是程序执行和资源管理的最小单位。可以用一个程序来创建许多进程。或者反过来说,许多进程运行的可以是同一个程序
进程类型
  1. 交互式进程:交互式进程经常与用户进行交互,需要等待用户的输入(键盘和鼠标操作等)。当接收用户的输入之后,这类进程能够立刻响应。典型的交互式进程有Shell命令进程、文本编程器和图形应用程序运行等
  2. 批处理程序:批处理程序不必与用户进行交互,因此通常在后台运行。由于这类进程通常不必很快地响应,因此往往不会优先调度。典型的批处理进程是编译器的编译操作、数据库搜索引擎等
  3. 守护进程:守护进程一直在后台运行,和任何终端都不关联。通常系统启动时开始执行,系统关闭时才结束。很多系统进程(各种服务)都是以守护进程的形式存在的

进程的状态

内核将所有进程存放在双向循环链表(进程链表)中,链表的节点都是task_struct结构体,称为进程控制块的结构。该结构包含了与一个进程相关的所有信息,如进程的状态、进程的基本信息、进程标识符、内核相关信息、父进程相关信息、与进程相关的终端信息、当前工作目录、打开的文件信息、所接收的信号信息等

进程状态
  1. 运行态(TASK_RUNNING):进程当前正在运行,或者正在运行队列中等待调度
  2. 可中断的睡眠态(TASK_INTERRUPTIBLE):进程处于阻塞(睡眠)状态。正在等待某些事情发生或能够占用某些资源。处在这种状态下的进程被信号中断。接收信号或被显示唤醒呼叫之后,进程将转变为运行(TASK_RUNNING)状态
  3. 不可中断的睡眠态(TASK_UNINTERRUPTIBLE):此进程状态类似可中断的睡眠,只是它不会处理信号,把信号传递到这种状态下的进程不能改变其状态。只有在它所等待的时间发生时,进程才显示地被唤醒呼叫
  4. 停止态(TASK_STOPPED):进程的执行被暂停。当进程接收SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOU等信号,就会进入暂停状态
  5. 僵尸态(TASK_ZOMBIE):子进程运行结束,父进程未退出,并且未使用wait()函数族(如使用waitpid()函数)等系统调用来回收子进程的资源。处在该进程下的子进程已经放弃了几乎所有的内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等供其父进程收集
  6. 消亡态:进程退出,不占用任何资源,更不会被调度,该状态不可见
进程标识符

Linux内核通过唯一的进程标识符(进程身份证号)PID(Process ID)来标识每个进程。 Linux中获得当前进程的进程号(PID)和父进程号(PPID)的系统调用函数分别为getpid()和getppid()

进程组与会话组

Linux系统中,进程是以组的形式(进程之间的层次关系)进程管理的,如进程组和会话组,进程组是一组相关进程的集合,会话组是一组相关进程组或进程的集合

进程的优先级

Linux和大多数其他UNIX实现一样,调度进程使用CPU默认模型是循环时间共享算法。在这种模型下,每个进程轮流使用CPU一段时间,这段时间被称为时间片。循环时间共享算法满足了交互式多任务系统满足两个重要需求

  1. 公平性:每个进程都有机会用到CPU
  2. 响应性:一个进程在使用CPU之前无须等待太长时间

在循环时间共享算法中,进程无法直接控制何时使用CPU以及使用CPU的时间。在默认情况下,每个进程轮流使用CPU直至时间片被用光或自己自动放弃CPU(如进程睡眠)。如果所有进程都试图尽可能地使用CPU,那么它们使用CPU的时间差不多是相等的

进程的特性nice值允许进程间接地影响内核的调度算法。每个进程都有一个nice值,其取值的范围为-20(高优先级)~19(低优先级),默认值为0。在传统的UNIX实现中,只有特权进程才能赋给自己(或其他进程)一个负(高)优先级。非特权进程只能降低自己优先级,即赋一个大于默认值0的nice值。

nice值是一个权重因素,它导致内核调度器倾向于调度拥有更高优先级的进程。给一个进程赋一个低优先级,并不会导致它完全无法用到CPU,但会导致它使用CPU的时间变少。nice值对进程调度的影响程序则根据Linux内核版本的不同而不同

进程的调度策略

在系统中有多个进程同时执行,单个CPU下,实际上任意时刻只能有一个进程处于执行状态,而其他进程则处于非执行状态。下面两种调度策略

  1. SCHED_RR策略

在SCHED_RR策略中,优先级相同的进程以循环时间分享的方式进行。进程每次使用CPU的时间为一个固定长度的时间片。一旦被调度执行之后,使用SCHED_RR策略的进程满足下列条件中的一个会放弃CPU的控制,否则会保持对CPU的控制

a. 时间片结束
b. 资源放弃CPU,如执行阻塞式的系统调用
c. 进程终止
d. 被一个优先级更高的系统调用

前两种情况中,进程放弃CPU之后,将会放置在与其优先级级别对应的队列的队尾。在最后一种情况中,当优先级更高的进程执行结束之后,被抢占的进程会继续执行知道其时间片的剩余部分被消耗完(被抢占的进程仍然位于其优先级级别对应的队列的队头)

  1. SCHED_FIFO策略

SCHED_FIFO策略(先入先出)与SCHED_RR策略类似。它们之间最主要的差别在于SCHED_FIFO策略中不存在时间片,如果一个SCHED_FIFO进程获得了CPU的控制权之后,它就会一直执行直到下面某个条件满足

a. 自愿放弃CPU
b. 进程终止
c. 被一个优先级更高的进程抢占

第一种情况中,进程会被放置在与其优先级级别对应的队列的队尾。在最后一种情况中,当高优先级进程执行结束后,被抢占的进程会继续执行

上述两种被抢占的原因可能有以下几种

  1. 之前被阻塞的高优先级进程解除阻塞了
  2. 另一个进程的优先级被提到了一个比当前进程的优先级高的级别
  3. 当前运行的进程优先级被降低到低于其他可运行的进程的优先级
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章