运行起来的程序?在内存中的程序?? ? 这样理解进程说明你还并不能把进程的概念描述清楚。
进程vs程序
程序是我们在编写代码之后编译链接生成的可执行程序。那进程呢?是把磁盘中的可执行程序通过加载拷贝的方式加载到内存中就是进程嘛?
其实在我们的程序加载到内存 之前一定会有一个老大哥——操作系统加载到内存中,而程序是操作系统将其进行加载拷贝到内存当中的。再来看,我们平常使用计算机的时候打开任务管理器发现不止一个进程在运行,如下图
是不是有多个进程在运行啊。那么说明操作系统内可能会同时存在多个“进程”,那么既然这么多“进程”,操作系统要不要管理所有的“进程”呢?答案是要。那么操作系统如何管理呢?结合我们前面冯诺依曼体系结构那篇文章的理解我们知道,应该先描述,再组织。操作系统是用C语言写的,所以操作系统要想管理进程,那么就必须用C语言来描述进程,通过进程的各种重要属性来描述进程,我们很容易想到结构体。这么多进程,结构体里面可以放一些结构体指针将他们链接起来,那么对进程的管理就转变成了对链表的增删查改。
上图中的PCB叫进程控制块,全称process control? block.
所以进程=可执行程序+内核数据结构(目前以PCB为例)
相比于程序,进程多了在内存中的内核数据结构,而这里的的内核数据结构就是为了方便操作系统对进程做管理。
进程概念:
课本概念:程序的一个执行实例,正在执行的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体。
描述进程-PCB:
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct。
task_struct-PCB的一种
在Linux中描述进程的结构体叫做task_struct。
task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。
task_ struct内容分类
标示符: 描述本进程的唯一标示符,用来区别其他进程。
状态: 任务状态,退出代码,退出信号等。
优先级: 相对于其他进程的优先级。
程序计数器: 程序中即将被执行的下一条指令的地址。
内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
其他信息
已经初步有了进程的框架了,那么我们下面开始来了解task_struct的核心字段都有哪些?
首先我们来谈谈进程的唯一标识符,叫做pid, 即process? id.
下面我们在linux系统下编写一段代码来演示进程的pid,包括如何获取进程的pid,如何通过指令查看进程的pid.
首先我创建一个自动化构建工具,输入touch Makefile
回车之后这个文件创建完毕,然后我们再创建一个mycode.c文件
然后vim Makefile
写上以下代码:
这样就可以通过简单的指令来编译代码,重新编译前可以将生成的可执行程序删除再编译,这样会更方便。
然后在mycode.c中写上以下代码:
1 #include<stdio.h>
2 #include<unistd.h>
3 int main()
4 {
5 int i = 0;
6 while(i<=100)
7 {
8 printf("我已经是一个进程了。。。。:%d\n",getpid());
9 sleep(1);
10 }
11 return 0;
12 }
保存退出之后输入 make指令会生成一个mycode的可执行程序,然后通过指令./mycode运行该程序
在linux系统下呢可以通过系统调用接口获取进程的pid,需要包含头文件#include<unistd.h>
运行之后是这样
然后我们可以通过(我用的是云服务器xshell)这个窗口右键复制SSH渠道可以再弹出一个相同用户的不同窗口,同样可以对该系统进行操作
然后输入这行命令就可以看到对应进程的PID的信息了,这里我们可以看到是1630
然后我输入kill -9 1630
把这个进程杀死了,另一个窗口的该进程则被停下来了
kill掉之后我们再去那个窗口查看这个进程是否还存在
发现该pid为1630的进程不见了
然后呢,我再通过运行该进程再进行查看
继续输入查看的指令发现又出现了。
而且pid变化了,变成了1946? 每次运行分配的pid都不一样。
但是他的PPID我们发现并没有改变。
所以呢,我们明显感觉到这就是进程。
我们运行的所有的指令,软件,自己写的程序,都是进程。
下面我们以windows为例,再解释以下进程
一开始我没有打开计算器的时候,没有计算器这个进程。
打开之后我们立马可以看到计算器这个进程。
想要更加了解Linux操作系统里面的进程PCB结构体的话可以去
linux内核源代码中下载源代码进行查看