进程的基本概念
正文开始@Assassin
目录:
1. 进程的清晰认识:
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程(process)是程序(program)的实体。
总结:
课本概念: 程序的一个执行实例,正在执行的程序等。
内核观点: 担当分配系统资源(CPU时间,内存)的实体。
ps:操作系统(OS)就是开机时启动的第一个进程。
代码进行编译链接后会生成一个可执行程序,这个可执行程序本质上是一个存放在磁盘上的文件。当双击这个可执行程序将其运行起来时,本质上是将这个程序加载到内存当中,此时CPU便可对其进行逐语句执行。而一旦将程序加载到内存后,便不应该称其为程序了,严格意义上应该将其称之为进程。
进程的各种状态:
一般说来,一个进程并不是自始至终连续不断地运行的,它与并发执行中的其他进程的执行是相互制约的。
它有时处于运行状态,有时又由于某种原因而暂停运行处于等待状态,当使它暂停的原因消失后,它又进入准备运行状态。
所以,在一个进程的活动期间至少具备三种基本状态,即运行状态、就绪状态、阻塞状态。
2. 描述进程的结构体-PCB:
操作系统中可以同时存在大量进程,使用命令ps aux
或者ps axj
便可以显示系统当中存在的进程。
[Assassin@Ninghai ~]$ ps aux
[Assassin@Ninghai ~]$ ps axj
计算机开机启动的第一个程序就是操作系统(即操作系统是第一个加载到内存的),大伙都知道操作系统是专业搞软硬件管理的软件,其中就包括了进程管理。click here!! 初步认识操作系统
个人认为操作系统搞管理的精髓是 —> " 先描述,再组织 "。
操作系统作为管理者是不需要直接和被管理者(进程)直接进行沟通的,当一个进程出现时(也就是将程序的代码+数据加载到内存时),操作系统便立即对其进行描述,之后对该进程的管理实际上就是对其描述信息的管理。
进程信息被放在一个叫做进程控制块的数据结构中(本质上是一个结构体struct),可以理解为进程属性的集合,称之为PCB(process control block)。
操作系统将每一个进程都进行描述,每个进程都有其相应的进程控制块(PCB),并将这些PCB以双链表的形式组织起来以便于更好地进行管理。所以说,进程是大于可执行程序的,A process is larger than an executable program,因为进程在可执行程序的代码+数据的基础上包含了描述信息PCB。
这样一来,操作系统只要拿到这个双链表的头指针,便可以访问到所有的PCB。此后,操作系统对各个进程的管理就变成了对这条双链表的一系列操作。
例如创建一个进程实际上就是先将该程序的代码和数据加载到内存,紧接着操作系统对该程序进行描述形成对应的PCB,并将这个PCB插入到双链表当中组织起来。同理,退出一个进程实际上就是先将该进程的PCB从双链表当中删除,然后操作系统再将内存当中属于该进程的代码和数据进行释放或是置为无效。
总的来说,操作系统对进程的管理实际上就变成了对双向链表的增、删、查、改等操作。
3. task_struct:
进程控制块PCB是一系列描述进程信息的结构体的统称,对应到linux操作系统上,PCB称为
task_struct
。
进程控制块PCB是描述进程信息的,在C++当中称之为面向对象class,在C语言当中称之为结构体,既然linux操作系统是用C语言进行编写的,那么linux当中的进程控制块必定是用结构体来实现的。
- PCB实际上是对进程控制块的统称,在linux中描述进程的结构体叫做
task_struct
task_struct
是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含进程的信息
具体task_struct
的代码可以到对应的linux内核中include/linux/sched.h
头文件中查看:
[Assassin@Ninghai temp]$ vim /usr/src/kernels/3.10.0-1160.53.1.el7.x86_64/include/linux/sched.h
代码量非常大:
4. task_struct内容分类:
task_struct
就是linux操作系统当中的进程控制块,task_struct
当中主要包含以下信息:
- 标示符pid: 描述本进程的唯一标示符,用来区别其他进程
- 状态status: 任务状态,退出代码,终止信号等
- 优先级priority: 相对于其他进程的优先级
- 程序计数器(pc): 程序中即将被执行的下一条指令的地址
- 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
- 上下文数据: 进程执行时处理器的寄存器中的数据
- I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表
- 记账信息: 可能包括处理器时间总和,使用的时钟总和,时间限制,记账号等
- 其他信息等
5. 查看进程:
5.1 proc目录查看进程:
在根目录下有一个名为proc的系统文件夹:
文件夹当中包含大量进程信息,其中有些子目录的目录名为数字:
这些数字其实是某一进程的PID,文件夹当中记录着对应进程的各种信息。例如查看目录名为1的文件夹,即为查看pid为1的进程信息:
5.2 通过ps指令查看:
使用ps aux
或者ps ajx
查看所有的进程信息,ps ajx
可以显示父进程id:
[Assassin@Ninghai ~]$ ps aux
[Assassin@Ninghai ~]$ ps ajx
要想单独查看某一特定进程的具体信息,可以ps搭配grep来使用:
[Assassin@Ninghai ~]$ ps aux | head -1 && ps aux | grep while | grep -v grep
6. 前台进程&&后台进程:
6.1 前台进程:
在linux操作系统中,只能有一个前台进程,比如用./
跑起来的进程都是前台进程:这里的procbar
就是一个前台进程。
前台进程运行起来时,是不能在shell中执行其他指令的,因为linux操作系统只允许有一个前台进程。杀死前台进程的方式一般是ctrl + c
终止,也可以另起一个终端使用kill -9
。
6.2 后台进程:
在前台进程的基础上加上一个 &,就可以使其变为后台进程:比如这里的while
进程
后台进程在执行后依旧可以执行其他指令,且后台进程不可被ctrl + c
终止掉:
杀死后台进程一般是使用kill -9
指令:
over~