Linux--进程概念

博客介绍了进程本质是运行中的程序,程序是硬盘中的可执行文件。阐述了fork复制父进程pcd,子进程从创建成功下一步指令开始运行。还模拟实现了孤儿和僵尸进程,分析了僵尸进程形成原因、危害,以及孤儿进程产生原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进程:本质为运行中的程序
程序:存储在硬盘中的可执行程序文件

	操作系统如何管理进程?先描述,后组织
	站在操作系统的角度来说,进程就是操作系统对进程的描述-->pcb(进程控制块)		
		struct task_struct结构体
		描述进程:标识符(PID),进程状态,优先级,内存指针,上下文数据,
				程序计数器,io状态信息,记账信息(cpu上运行时间)
	进程的切换调度:cpu的分时技术---时间片
	查看进程:ls /proc/		ps -ef		aux 	top(显示前几个)		getpid函数(进程ID)
	进程的创建:
	fork()	操作系统提供创建进程的接口

fork通过复制父进程的pcd,意味着子进程跟父进程代码和数据指向的是同一块内存区域(数据跟代码运行的完全一样),并且子进程拷贝了程序计数器,上下文数据,所以当前的子进程是从子进程创建成功的下一步指令开始运行的.

父子进程代码共享,数据独有
	为什么创建子进程:分摊压力,运行其他任务
	如何分辨子进程:父子进程的返回值不同
	返回值:在父进程中,返回子进程id(pid>0);在子进程中返回0
			我们用户就是通过返回值对父子进程进行代码分流
	进程状态:阻塞、运行、就绪
		linux下的进程状态:
			运行 R
			可中断睡眠 S 
			不可中断睡眠 D
			停止 T
			僵尸 Z
			追踪 X
		僵尸进程:处于僵死状态的进程
			危害:资源泄漏
			产生:子进程先于父进程退出,操作系统通知父进程,但是父进程没有管,操作系统不敢
					擅自释放子进程所有资源,一旦释放就没有地方保存退出原因,因此子进程就成了僵尸进程
					。操作系统不释放的原因是:子进程退出原因保存在pcb中。
			处理:退出父进程
			预防:进程等待
		孤儿进程:父进程先于子进程退出,孤儿进程的父进程变为1号进程init进程,并且孤儿进程退出
					不会产生僵尸进程
		守护进程/精灵进程:特殊的孤儿进程
进程优先级:数字
	功能:决定cpu资源的优先分配权
	查看:ps -l
	PRI	NI
	优先级无法直接修改,但是可以通过设置NI的值而对优先级进行设置
	nice值的取值范围[-20~19]
	PRI = PRI + NI
	优先级的修改方法:
		nice -n	ni_val ./main
		renice -n ni_val -p pid
进程的相关概念:竞争性:进程之间对于资源具有竞争性
				独立性:进程之间应该相互独立
				并行:进程同时在cpu上运行
				并发:进程切换在cpu上运行
环境变量:用于存储操作系统运行环境参数的变量->操作系统运行配置更加方便
	查看:env	set		echo(指定$环境变量名称)
	声明:export
	删除:unset
	作用:让程序运行更加高效,因为环境变量具有全局特性
	如何在代码中获取环境变量:getenv()	main的第三个参数	全局变量char** environ
程序地址空间:
	虚拟地址空间(mm_struct结构体)这个结构体是进程对内存的描述(内存描述符)
	为什么要用虚拟地址空间?
		提高内存利用率,增加内存访问控制;保证进程的独立性
	程序地址空间:每一个程序都有自己的程序地址空间
	内存地址:内存区域的编号
	进程地址空间:代码共享,数据独有
	写时拷贝技术
	我们所说的程序地址空间,实际上是一个进程的虚拟地址空间,目的是为了告诉进程,
		每个进程都有一个完整连续的内存,但是真正一个进程使用的内存经过页表映射后可能只
			使用了很少一部分物理内存。
	使用页表虚拟地址空间,记录映射关系,内存访问控制。
	页表:记录虚拟内存与物理地址的映射关系,并且对内存进行访问控制
	分页式内存管理:提高内存利用率
进程调度:cpu调度进程其实调度的是pcb
	大O(1)调度算法:用空间换时间
		有多少优先级就使用多少队列,用位图记录各个优先级队列中是否有进程,
			调度完成后,有同样的队列记录过期的进程全部调度完毕后,交换指针,新的队列
				就变为旧的,旧的变为新的队列。

模拟实现孤儿进程和僵尸进程

// 模拟实现僵尸进程
#include <stdio.h>                                                                                          
#include <unistd.h>
#include <stdlib.h>

 int main()
 {
         pid_t pid;
         pid = fork();
         if(pid < 0)
         {
                 perror("fork error:");
                 exit(1);
         }
         else if(pid == 0)
         {
                 sleep(1);
                 printf("child exit!\n");
         }
         else 
         {
                 while(1)
                 {
                         printf("I am busy!\n");
                         sleep(3);
                 }
          }
          return 0;
}                 

僵尸进程
僵尸进程的形成原因就是子进程先于父进程退出,操作系统告诉父进程查看退出原因(退出原因保存在pcb中),但是父进程正在做其他事情,来不及去处理,操作系统不能擅自释放,子进程就形成了僵尸进程。
僵尸进程的主要危害就是造成资源浪费,其实僵尸进程的大部分资源已经被操作系统释放,但是僵尸进程内核(pcb)中的资源不能释放,所以就造成了资源泄露。

// 模拟实现孤儿进程
#include <stdio.h>                                                                                          
#include <unistd.h>
#include <stdlib.h>

 int main()
 {
         pid_t pid;
         pid = fork();
         if(pid < 0)
         {
                 perror("fork error:");
                 exit(1);
         }
         else if(pid == 0)
         {
                while(1)
                {
                	printf("I am child, my parent is %d\n", getppid());
                	sleep(2);
                }
         }
         else 
         {
         		sleep(1);
         		printf("I am parent, exit\n");
         }
          return 0;
}    

孤儿进程
在这里插入图片描述
孤儿进程的产生原因是父进程先于子进程退出,子进程的父进程自动变为1号init进程,孤儿进程不会产生僵尸进程,可以理解为孤儿进程只是换了一个父进程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值