进程的概念
上篇文章我们介绍了冯诺依曼体系结构和了解了操作系统的概念和功能;在我们Windows的计算机上的磁盘上有很多的可执行程序,其中有我们自己手动安装的或者自己写的可执行程序的代码等等各种功能的程序。当我们想启动某一程序时,只需要双击它的图标即可。根据冯诺依曼体系结构操作系统便将我们执行的可执行程序从磁盘加载到内存中,此时这个可执行程序在内存中就执行起来了,便是一个我们所谓的进程。
· 课本概念:程序的一个执行实例,正在执行的程序等
· 内核观点:担当分配系统资源(CPU时间,内存)的实体。
这就是我计算机此时后台进程和运行起来的程序,我们会发现后台的进程不止一个运行起来的程序也不知一个;就像我现在一边在这里写文章一边还是用音乐播放器放着我喜欢的音乐,甚至在阅读参考文档等等运行了很多我使用到的程序,互不干扰每个运行起来的可执行程序只发挥着自己的作用。
进程的管理
当我们启动计算机的那一刻,操作系统这款软件就率先运行起来;上篇文章我们详细谈到操作系统的作用:对软硬件资源进行管理和操作系统的核心之一:进程管理。一个软件加载到内存中运行起来便是一个进程,操作系统的管理方式——先描述,在组织。
描述进程——pcb
进程加载到内存中内存操作系统会分配空间地址(ID)(代码地址&数据地址),记录此时我们是否在使用(状态)等等各种属性,操作系统将这些能够描述一个加载在内存中的程序的属性打包起来(struct),这个struct便是一个进程的pcb(process control block)。
· 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
· 课本上称之为PCB(process control block),Linux操作系统下的PCB是: task_struct
组织进程
加载到内存中的可执行程序,操作系统会形成它的pcb,每个pcb不仅仅含有描述对应运行软件的各种属性,还有指向下一个运行起来程序的pcb(也就是结构体指针)。将每个pcb以链表的方式组织起来,其实就是对进程的管理被建模成对链表的增删查改。
进程在排队
当我们运行起来的程序需要进入CPU进行数据运算时,会被CPU调度一次;当运行起来很多程序时,每个程序都有自己的pcb;将需要被CPU调度的软件的pcb以队列的形式组织起来,先进先出;这便是进程在排队;
总结:
· 操作系统并不是直接对运行起来的可执行程序做管理,而是对运行起来的可执行程序“打包”(pcb),每个pcb做管理。
· 进程的深层含义:进程=可执行程序+内核数据结构(pcb)
· 进程的pcb不止在一个链表中,可能在很多结构中;例如:当程序运行起来并且需要CPU调度时pcb不仅在链表中,还在一个队列中排队。
Linux下的进程
task_struct——PCB的一种
· 在Linux中描述进程的结构体叫做task_struct。
· task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息
task_struct内容分类
· 标示符: 描述本进程的唯一标示符,用来区别其他进程。(pid)
· 状态: 任务状态,退出代码,退出信号等。
· 优先级: 相对于其他进程的优先级。
· 程序计数器: 程序中即将被执行的下一条指令的地址。
· 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
· 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
· I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
· 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
· 其他信息
Linux组织进程
可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。
查看进程
指令
· ps ajx
· ps指令还有很多的选项,目前我们我们就只介绍这一个选项在以后的文章中会慢慢介绍剩下的选项。
下图为我当前Linux下的部分进程。
查看可执行程序的进程
我们自己使用编程语言写的.c文件不是可执行程序,需要通过预处理、编译、链接生成后缀为.exe的可执行程序,运行这个可执行程序在系统中会生成进程。
#include<stdio.h> #include<unistd.h> int main() { int i=0; while(i<100) { printf("我是一个进程!\n"); sleep(1); i++; } return 0; }
上图我们执行可执行程序后通过管道过滤会查到我们可执行程序运行时的进程。
总结:
· 我们执行的程序、写的可执行程序、执行的代码都是进程
我们可以通过函数调用得到我们的pid。
1 #include<stdio.h> 2 #include<unistd.h> 3 #include<sys/types.h> 4 int main() 5 { 6 int i=0; 7 while(i<100) 8 { 9 pid_t id =getpid(); 10 printf("我是一个进程,我的进程id是:%d\n",id); 11 sleep(1); 12 i++; 13 } 14 return 0; 15 }
"杀掉进程"
使用kill指令配合进程的pid就可以”杀掉进程“