linux 之进程基础 (一)、 进程的基本概念

1.进程中的基本概念

1.1 什么是进程?

可以认为进程是一个程序的一次执行过程,或者说一个正在执行的程序。在这个过程中,伴随着资源的分配和释放。进程是资源管理的最小单元。

1.2 进程与程序的区别与联系?

程序是存放在硬盘中的二进制文件(可执行指令的序列),是静态的。而进程是已经加载到主存中,正在执行的程序。它是程序执行的过程,包括创建、调度和消亡。在这个过程中,伴随着资源的分配和释放,是动态的。

1.3 进程在系统中的体现?

1.3.1 可执行文件(elf) 文件的格式

在这里插入图片描述
elf文件中包括很多个字段,当程序执行时需要根据字段信息将程序加载到主存中。其中最重要的两个字段为:

  • 代码段(text)(即可执行的指令)
  • 数据段(data)(运算的中间数据)
1.3.2 进程的内存分布

在这里插入图片描述

  • 代码区
    程序(函数)代码所在,由编译而得到的二进制代码被载入至此.代码区是只读的!有执行权限.值得注意的是,字符串字面值(如"Hello World")就存储在这个区.
  • 数据段和BSS段
    合称静态区(全局区),用来存储静态(全局)变量.区别是 前者(数据段)存储的是已初始化的静态(全局)变量,可读写.后者(BSS段)存储的是未初始化的静态(全局)变量,可读写.

  • 自由存储区.不像全局变量和局部变量的生命周期被严格定义,堆区的内存分配和释放是由程序员所控制的.

  • 由系统自动分配和释放.存储局部(自动)变量.
1.3.3 进程在系统中的体现

如上述,一个程序,实际上的格式为一个elf 文件,当执行该程序时,首先按照elf文件的各个段,将该程序从硬盘按照上述图表所示加载到主存中,程序存在于一个进程的用户空间,而在内核空间中,维护了一个很大的结构,用于标识该进程的执行的状态。这个结构的名字叫:

struct task_struct
{
...//(非常大)
}

我们介绍这个结构的一些比较重要的字段:

  • state: 表示进程的状态信息

  • rt_priority: 表示进程的运行优先级

  • struct mm_struct * mm:该结构体记录了进程内存使用的相关情况,虚拟地址的概念可以提一下

  • pid_t pid 进程号,是进程的唯一标识

  • pid_t tgid 线程组id号

  • struct fs_struct * fs 它包含此进程当前工作目录和根目录

  • struct files_struct * files :打开的文件相关信息结构体。f_mode字段描述该文件是以什么模式创建的:只读、读写、还是只写。f_pos保存文件中下一个读或写将发生的位置

  • 处理器相关上下文: 一个进程可以被认为是系统当前状态的总和。每当一个进程运行时,它要使用处理器的(PC,各种寄存器,堆栈指针,堆指针等),这是进程的上下文(context)。并且,每当一个进程被暂停时,所有的CPU相关上下文必须保存在该进程的task_struct中。当进程被调度器重新启动时其上下文将从这里恢复。

1.4 进程的类型有哪些?

  • 交互进程
    是由一个Shell启动的进程。这类进程经常与用户进行交互,所以一般优先级较高。交互进程:既可以在前台运行,也可以在后台运行。
  • 批处理进程
    该类进程不属于某个终端,它被提交到一个队列中以便顺序执行(是一个进程序列,该进程负责按照顺序启动其它进程)这类进程不必与用户交互因此通常在后台运行。
  • 系统守护进程
    该类进程在后台运行。它一般在Linux启动时开始执行,系统关闭时才结束。

1.5 进程的状态有哪几个?

  • 可运行态状态(R TASK-RUNNING)
    此时进程正在运行,或者正在运行队列中等待调度。

  • 可中断睡眠态(S TASK_INTERRUPTIBLE)
    此时进程正处于阻塞(睡眠)状态,正在等待某些事件发生或者能够炸弄某些资源。例如设备初始化完成、I/O 操作完成或定时器到时等。处在这种状态下的进程可以被信号中断。进程会在等待的事件发生或者是接收到信号被唤醒,进程转变为(TASK_RUNINNG状态)。

  • 不可中断睡眠态(D TASK_UNINTERRUPTIBLE)
    与TASK_INTERRUPTIBLE状态类似,进程处于睡眠状态,但是此刻进程是不可中断的。信号传递给这种状态下的进程不能改变它的状态。只有在它等待的事件发生时,进程才被显示的唤醒。

  • 暂停态(T TASK_STOPPED)
    进程的执行被暂停,当进程收到SIGSTOP、SIGTSTP、SIGTTIN、SIGTTOU等信号,就会进入暂停态。向进程发送一个SIGCONT信号,可以让其从TASK_STOPPED状态恢复到TASK_RUNNING状态。

  • 僵尸态 (Z EXIT_ZOMBIE)
    子进程运行结束,但是父进程尚未回收子进程的退出状态。处于这种状态下的进程已经放弃所有了几乎所有的资源,除了task_struct结构(以及少数资源)以外。于是进程就只剩下task_struct这么个空壳,这个task_struct的空壳就形象地被称为僵尸。

  • 消亡态(X EXIT_DEAD)
    父进程回收了子进程了退出状态后,进入的最终状态。这意味着接下来该进程将被彻底释放。所以EXIT_DEAD状态是非常短暂的,几乎不可能通过ps命令捕捉到。

注意:运行top命令 可以查看进程的运行状态, S列代表运行状态。

1.5.2 状态转换图

在这里插入图片描述

1.6 进程的运行模式

1.6.1 进程的运行状态

进程的执行模式分为用户模式内核模式,也称为用户态和内核态。处于用户模式的进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间的虚拟地址。
在这里插入图片描述
注意:
内核空间的是有内核负责映射的,它不会随着进程的改变,是固定的。内核空间地址有自己对应的页表,用户进程各自有不同的页表。每个进程的用户空间都是完全独立、互不相干。

1.6.2 状态切换

用户模式的进程只有通过使用系统调用,或者中断的方式,才能切换到内核模式,访问内核空间。

1.6.3 状态切换举栗子

在这里插入图片描述
系统调用其实也是通过中断实现的,系统调用的中断号为0x80。每个中断会有中断处理函数,系统调用的中断处理函数为systemcall(),func()函数会将中断号和系统调用号一起传递给内核。内核根据系统调用号执行系统调用处理函数,例如open() 函数最终调用的就是system_open() 系统调用处理函数,然后返回一个文件描述符给用户。

posted @ 2020-03-24 22:26  江南又一春  阅读(491)  评论(0编辑  收藏  举报