什么是进程
冯诺依曼体系结构
输入设备:采集获取数据(键盘)
输出设备:数据输出(显示器)
存储器:内存/
运算器+控制器:中央处理器CPU
硬件结构决定软件行为。
所有硬件都是围绕内存工作的。
**操作系统:**系统内核+外部应用。管理计算机上的软硬件资源。
进程概念
运行中的程序。进程就是一个PCB。是一个运行中程序的描述,通过描述信息中的内存指针能够找到内存中运行的程序代码以及数据,并且通过上下文数据可以保存程序调度切换时正在处理的数据,以及通过程序计数器保存进程切换时程序即将执行的下一步指令,等等…通过这些描述信息实现控制一个程序的运行,因此对于一个操作系统来说进程就是PCB。
进程在操作系统中是调度切换运行的,每个进程都有一个CPU时间片(一个进程在CPU上的运行时间段),在CPU上时间片运行完毕后则切换到下一个进程–CPU分时机制。
PCB
一个CPU同一时间只能处理一个进程,其他进程就会处于阻塞状态。为了提高处理效率,CPU采取分时技术(每个进程CPU只处理很短的时间)。那么问题来了,CPU在处理一个进程的时候怎么知道它上次处理这个进程处理到哪里了?所以就有了PCB(process control block,进程控制块–存放进程信息的数据结构,Linux中的PCB是task_struct)。
task_struct内容分类:
内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
上下文数据:保存上次正在运行的数据(休学例子)
程序计数器:程序中即将被执行的下一条指令的地址。
标识符(ID):描述本进程的唯一标识符,用来区别其他进程(学生学号)。
状态:任务状态,退出等。
优先级:执行的优先性。
记账信息:包含处理器时间总和,时间限制(人类年龄)。
进程的创建和查看
查看进程信息
ps -ef
e:查看所有进程信息
f:树状展开
ps aux
显示所有包含其他使用者的行程
ps -ef | grep loop
杀死进程
kill
kill 进程ID //杀死普通进程
kill -9 进程ID //强制杀死
进程状态
运行/就绪/阻塞
Linux下进程状态:
运行状态R:正在运行的以及只要拿到时间片就能运行的
可中断休眠状态S:可以被中断的阻塞状态
不可中断休眠状态D:
停止状态T:
僵死状态Z:进程已经退出但是资源没有完全释放
僵尸进程
僵尸进程的产生原因是什么?
子进程先于父进程退出,退出后,为了保存自身的退出原因(返回值),因此资源没有完全释放(PCB),操作系统这时候通知父进程获取子进程的退出状态,并允许操作系统释放资源,但是如果父进程没有关注到这个退出状态,则子进程虽然退出,但是资源没有完全被释放,处于僵死状态,成为僵尸进程。(猝死,家人,警察例子)
僵尸进程的危害是什么?
资源泄露。
僵尸进程代码演示:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(){
printf("***********%d\n",getpid());
pid_t pid=fork();
if(pid<0){
printf("fork error\n");
}else if(pid==0){
printf("this is child--%d\n",getpid());
sleep(5);
exit(0);
}else{
printf("this is father--%d\n",getpid());
}
while(1){
printf("------------%d\n",getpid());
sleep(1);
}
return 0;
}
运行结果:
孤儿进程
父进程先于子进程退出,子进程成为孤儿进程在系统后台运行(例如S+是在前台运行,S是在后台运行),被1号init进程收养。
孤儿进程代码演示:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(){
printf("******\n");
pid_t pid=fork();
if(pid>0){
sleep(5);
exit(0);
}
while(1){
printf("hello\n");
sleep(1);
}
return 0;
}
进程优先级
决定进程CPU调度优先权级别。优先级越小越早被执行
环境变量
用于存储系统运行环境参数的变量—使系统的参数配置更加灵活。
向进程传递参数。
env:查看所有的环境变量
export:将一个变量设置为环境变量
set:查看所有变量信息
程序地址空间
程序地址空间如下图:
内存地址:内存区域的编号。
每个进程都有一个自己的进程地址空间。
创建子进程—父子进程代码共享,数据独有。
我们在进程中所访问到的地址实际都是一个虚拟地址
程序地址空间->进程地址空间->虚拟地址空间
虚拟地址空间:通过一个结构体描述出一块完整的连续的线性的地址空间(mm_struct结构体–内存描述符)。
父子进程代码共享,数据独有,代码演示:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int gval=10;
int main(){
pid_t pid=fork();
if(pid==0){
gval=100;
printf("child=%d,%p\n",gval,&gval);
}else if(pid>0){
sleep(3);
printf("father=%d,%p\n",gval,&gval);
}
return 0;
}
运行结果:
解释: 这里打印出来的地址是虚拟地址而不会物理地址,这里是采用的写实拷贝技术,代码共享,数据独有。子进程在开始复制父进程时,页表也会拷贝的,只是在子进程要修改数据时会给子进程申请新的物理地址来存放修改的数据。
顺序存储数据:内存利用率低。
离散式存储数据:使用虚拟地址映射物理地址来实现离散存储数据。
页表:记录虚拟地址与物理地址之间的映射关系。
操作系统通过虚拟地址空间向进程描述了一个完整的连续的虚拟地址空间,供进程使用,但是在物理内存中进程数据存储采用离散式存储(提高内存利用率),并且使用页表映射虚拟地址与物理地址的映射关系,并且在页表中可以实现内存访问控制(标志位表示内存的访问权限)。
如何通过虚拟地址得到物理地址:分段式内存管理/分页式内存管理/段页式内存管理
今天的文章进程概念_进程的含义分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/68557.html