【Linux学习笔记十四】Linux 进程概念

Linux进程简介

  • 进程与程序
  • 进程的衍生
  • 工作管理

进程与程序

程序只是一些列指令的集合,是一个静止的实体,而进程不同,进程有一下的特性

  • 动态性:进程的实质是进程实体的一次执行的过程,有创建,撤销等状态的变化。而程序是一个静态的实体
  • 并发性:进程可以做到在一个时间段内,有多个程序在运行中。程序只是静态的实体,所以不存在并发行
  • 独立性:进程可以独立分配资源,独立接受调度,独立的运行。
  • 异步性:进程以不可预知的速度向前推进。
  • 结构性:进程拥有代码段、数据段、PCB(进程控制块,进程存在的唯一标志)。也这是进程的结构性才可以做到独立的运行

引入进程是因为传统意义上的程序已经不足以描述 OS 中各种活动之间的动态性、并发行、独立性还有相互制约性。就比如程序就像一个公司,只是一些证书,文件的堆积(静态实体)。而当公司运作起来就有各个部门的区分,财务部,技术部,销售部等等,就像各个进程,各个部门之间可以独立运做,也可以有交互(独立性、并发性)

而随着程序的发展越做越大,又会继续细分,从而引入了线程的概念,当代多数操作系统、Linux 2.6及更新的版本中,进程本身不是基本运行单位,而是线程的容器。就像上述所说的,每个部门又会细分为各个工作小组(线程),而工作小组需要的资源需要向上级(进程)申请。

并发与并行

  • 并发在一个时间段内,宏观来看有多个程序都在活动,有条不紊的执行
  • 并行在每一个瞬间,都有多个程序都在同时执行,这个必须有多个 CPU 才行

简而言之,一个程序至少有一个进程,一个进程至少有一个线程。线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。

进程的分类

  • 以进程的功能与服务的对象来分
    • 用户进程:通过执行用户程序、应用程序或称之为内核之外的系统程序而产生的进程,此类进程可以在用户的控制下运行或关闭。
    • 系统进程:通过执行系统内核程序而产生的进程,比如可以执行内存资源分配和进程切换等相对底层的工作;而且,该进程的运行不受用户的干预,即使是root用户也不能干预系统进程的运行。
  • 以应用程序的服务类型来分
    • 交互进程:由一个 shell 终端启动的进程,在执行过程中,需要与用户进行交互操作,可以运行于前台,也可以运行在后台。
    • 批处理进程:该进程是一个进程集合,负责按顺序启动其他的进程。
    • 守护进程:守护进程是一直运行的一种进程,经常在 Linux 系统启动时启动,在系统关闭时终止。它们独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。例如httpd进程,一直处于运行状态,等待用户的访问。还有经常用的 cron(在 centOS 系列为 crond) 进程,这个进程为 crontab 的守护进程,可以周期性的执行用户设定的某些任务。

进程的衍生

进程有这么多的种类,那么进程之间定是有相关性的,而这些有关联性的进程又是如何产生的,如何衍生的?

就比如我们启动了终端,就是启动了一个 bash 进程,我们可以在 bash 中再输入 bash 则会再启动一个 bash 的进程,此时第二个 bash 进程就是由第一个 bash 进程创建出来的,他们直接又是个什么关系?

我们一般称呼第一个 bash 进程是第二 bash 进程的父进程,第二 bash 进程是第一个 bash 进程的子进程,这层关系是如何得来的呢?

关于父进程与子进程便会提及这两个系统调用 fork() 与 exec()

fork-exec是由 Dennis M. Ritchie 创造的

fork() 是一个系统调用(system call),它的主要作用就是为当前的进程创建一个新的进程,这个新的进程就是它的子进程,这个子进程除了父进程的返回值和 PID 以外其他的都一模一样,如进程的执行代码段,内存信息,文件描述,寄存器状态等等

exec() 也是系统调用,作用是切换子进程中的执行程序也就是替换其从父进程复制过来的代码段与数据段

进程组与 Sessions

每一个进程都会是一个进程组的成员,而且这个进程组是唯一存在的,他们是依靠 PGID(process group ID)来区别的,而每当一个进程被创建的时候,它便会成为其父进程所在组中的一员。

一般情况,进程组的 PGID 等同于进程组的第一个成员的 PID,并且这样的进程称为该进程组的领导者,也就是领导进程,进程一般通过使用 getpgrp() 系统调用来寻找其所在组的 PGID,领导进程可以先终结,此时进程组依然存在,并持有相同的PGID,直到进程组中最后一个进程终结。

与进程组类似,每当一个进程被创建的时候,它便会成为其父进程所在 Session 中的一员,每一个进程组都会在一个 Session 中,并且这个 Session 是唯一存在的,

Session 主要是针对一个 tty 建立,Session 中的每个进程都称为一个工作(job)。每个会话可以连接一个终端(control terminal)。当控制终端有输入输出时,都传递给该会话的前台进程组。Session 意义在于将多个jobs囊括在一个终端,并取其中的一个 job 作为前台,来直接接收该终端的输入输出以及终端信号。 其他jobs在后台运行。

  • 前台(foreground)就是在终端中运行,与你能有交互的
  • 后台(background)就是在终端中运行,但是你并不能与其任何的交互,也不会显示其执行的过程

工作管理

bash(Bourne-Again shell)支持工作控制(job control),而sh(Bourne shell)并不支持。

并且每个终端或者说 bash 只能管理当前终端的中的 job,不能管理其他终端中的 job。比如我当前存在两个 bash 分别为 bash1、bash2,bash1 只能管理其自己里面的 job 并不能管理 bash2 里面的 job

我们都知道当一个进程在前台运作时我们可以用 ctrl + c 来终止它,但是若是在后台的话就不行了,并且在一个终端 bash 中只能管理当前 bash 里的 job.

我们可以通过 & 这个符号,让我们的命令在后台中运行

ls &
jobs显示工作任务
fg %num把工作任务放到前台
bg $num把工作任务放到后台
kill -signal %jobnumber杀掉工作任务

其中常用的有这些信号值
信号值 作用

  • -1 重新读取参数运行,类似与restart
  • -2 如同 ctrl+c 的操作退出
  • -9 强制终止该任务
  • -15 正常的方式终止该任务

注意

若是在使用kill+信号值然后直接加数字的话,这个数字代表的是 pid,你将会对 pid 对应的进程做操作
若是在使用kill+信号值然后%jobnumber,这时所操作的对象才是 job,这个数字就是就当前 bash 中后台的运行的 job 的 ID

发表评论

电子邮件地址不会被公开。 必填项已用*标注