目录
孤儿进程
进程的优先级
用top命令去修改优先级
其他概念
环境变量
PATH
获取环境变量
习题
父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?
父进程先退出,子进程就称之为“孤儿进程”
孤儿进程被1号init进程领养,当然要由init进程回收。
写一份代码测试孤儿进程一开始子进程是4222,父进程是4221
当父进程退出后,4222的父进程变为1
被回收会子进程的程序还在运行,屏幕仍然在滚动,我们输入kill -9 4222 即可杀掉子进程
总结:父进程退出,子进程还在,子进程就叫孤儿进程,孤儿进程会被1号进程领养(init,系统本身)
领养的目的是为了回收子进程
为什么要有优先级?
因为CPU是有限的,进程太多,需要通过某种方式竞争资源,优先级是用来确认谁先获得某种资源,谁后获得,我们可以用一些数据表面优先级
Linux优先级:优先级=老的优先级+nice值
程序运行起来之后,使用ps -la,pri是优先级,ni是nice值
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值,其表示进程可被执行的优先级的修正数值
PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为: PRI(new)=PRI(old)+nice
这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行所以,调整进程优先级,在Linux下,就是调整进程nice值
nice其取值范围是-20至19,一共40个级别
输入top,然后输入r,renice就是对nice值重新设置
输入要修改的PID,按回车
输入修改后的nice值
由于nice的范围是-20-19,所以如果我们renice 20,nice会变为19
我们再次renice 15,此时优先级应该是95+15=110,而我们查看时候却是95,这是因为每次设置的时候,都要从进程最开始的优先级开始,最开始的优先级是80,也就是老优先级是80
由于nice值是-20-19,且每次从80开始设置,所以优先级范围是60-99,这是因为操作系统要对各种资源进行均衡,做到雨露均沾。防止恶意调动
优先级=老的优先级+nice值
竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发CPU里面存有大量寄存器,如果CPU在运行进程A,CPU的寄存器里面,一定保存的是A的临时数据(如形参,形参的返回值),这些临时数据叫做A的上下文
上下文数据不能被丢弃
如果进程里正在运行A,此时切换到了进程B,进程A暂时被切换走的时候,需要进程A顺便带走自己的上下文数据,带走暂时保存的目的:为了下次回来的时候,能恢复上去,就能继续按照之前的逻辑向后运行,就如同没有中断过一样
cpu内的寄存器只有一份,但是上下文可以有多份,分别对应不同的进程
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash。
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性1.echo: 显示某个环境变量值
2. export: 设置一个新的环境变量(导出环境变量到当前BASH)
3. env: 显示所有环境变量
4. unset: 清除环境变量
5. set: 显示本地定义的shell变量和环境变量
ls是一个文件,我们可以直接使用ls,也可输入ls的路径运行ls
但对于我们自己写的程序,直接输入文件名,是不能运行的,如果想运行必须加上./表面路径
出现这种情况是因为跟环境变量有关系,如果想输入自己的文件名,直接运行文件,我们需要对环境变量进行设置
环境变量PATH,我们写的程序并不在环境变量所维护的路径下,所以不能直接用文件名运行
查看环境变量
如果想用文件名运行,我们可以把我们的文件移动到上面的任何一个路径里,但不推荐这种做法,这种做法会污染别人的命令池
我们可以将我们当前的路径放到环境变量里
这时就能直接运行
查看linux下的所有环境变量,输入env
我们也可修改PATH所在路径,但是输入指令之后会不起作用
我们ctrl+d重新登陆一下即可
系统中还有home和shell
home是我们的家目录
main函数最多可以有三个参数int main(int argc,char *argv[],char *env[])
argc和argv是命令行参数,
这就是命令行参数(启动程序时,给程序传入的选项),argc决定argv数组的大小,数组里放的是选项,命令行参数是通过父进程继承的,最开始的父进程为BASH
env是环境变量参数。是一个指针数组类型,我们可通过env[i]数组来获取环境变量
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
运行后直接查看环境变量
这样也可获取环境变量
libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。
运行后直接查看环境变量
但这俩种获取环境变量的方法都不太推荐
输入man getenv,查看使用规则
环境变量是从父进程继承下来的,最开始的环境变量来自BASH,因此环境变量具有全局属性一开启机器BASH就会运行
如果这样直接获取BASH中没有的环境变量会报错
用export给BASH导入环境变量
通过查询BAHS中没有test_game_over这个环境变量,我们直接导入,重启后就没了
定义一个变量
我们查看这个变量时,发现找不到,这是因为这个变量不是环境变量,虽然被定义出来了,虽然也在上下文当中,但环境变量里没找到它
我们使用set命令,set命令可以把系统的所有环境变量和私有变量都显示出来,env只显示与环境变量相关的东西,但此时my_name_is仍然不是环境变量
命令行可以定义俩种变量一种是局部变量例如my_name_is
还有一种环境变量,需要前面加export
1.关于 linux 的进程,下面说法不正确的是(A)
A.僵尸进程会被 init 进程接管,不会造成资源浪费;
B.孤儿进程的父进程在它之前退出,会被 init 进程接管,不会造成资源浪费;
C.进程是资源管理的最小单位,而线程是程序执行的最小单位。Linux 下的线程本质上用进程实现
D.子进程如果对资源只是进行读操作,那么完全和父进程共享物理地址空间。
A 僵尸进程指的是进程退出后不会完全释放资源,会造成系统资源泄漏;
B 孤儿进程在父进程退出后,父进程成为init进程,进程退出,孤儿进程的资源将被init进程释放
C 操作系统通过pcb实现对程序运行调度控制
D fork系统调用通过复制父进程创建一个子进程,父子进程数据独有,代码共享(在数据不发生改变的情况下父子进程资源指向同一块物理内存空间(调研写时拷贝技术))
2.下列有关进程的说法中,错误的是? [多选]
A.进程与程序是一一对应的
B.进程与作业是一一对应的
C.进程是静态的
D.进程是动态的过程
程序是静态的指令集合,保存在程序文件中,
进程是程序的一次运行过程中的描述。
作业是用户需要计算机完成的某项任务,是要求计算机所做工作的集合。
根据以上概念理解:
- A选项错误,因为一个程序可以同时运行多次,也就有了多个进程
- B选项错误,因为一个作业任务的完成可由多个进程组成,且必须至少由一个进程组成
- C选项错误,因为程序是静态的,而进程是动态的。
- D选项正确
3.系统感知进程的唯一实体是()
A.进程id
B.进程控制块
C.进程管理器
D.进程名
进程是操作系统对于程序运行过程的描述,而这个描述学名叫做进程控制块-PCB,它是操作系统操作系统管理以及调度控制程序运行的唯一实体。
根据进程的理解分析:
- A选项错误,因为进程ID只是进程的标识符,是系统能够找到特定进程的标识而已
- C选项错误,进程管理器只是对大量PCB进行管理的一个程序而已
- D选项错误,进程本质上来说没有名字,它有所调度管理运行的程序的名称,它的标识是进程ID,可以理解进程ID是它的名字
- 因此只有B选项正确,在系统角度看来,进程就是对于程序运行的描述,就是PCB进程控制块。
4. 在抢占式多任务处理中,进程被抢占时,哪些运行环境需要被保存下来?[多选](ACD)A.所有cpu寄存器的内容
B.全局变量
C.页表指针
D.程序计数器
A 所有cpu寄存器的内容 cpu上正在处理的数据
B 全局变量 程序内的数据(并不一定正在被处理)
C 页表指针 程序切换时会将页表起始地址加载到寄存器中
D 程序计数器 下一步程序要执行的指令地址
5.下面有关孤儿进程和僵尸进程的描述,说法错误的是 D?
A.孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。
B.僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
C.孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
D.孤儿进程和僵尸进程都可能使系统不能产生新的进程,都应该避免
根据答案选项理解正确描述
僵尸进程:子进程先于父进程退出,父进程没有对子进程的退出进行处理,因此子进程会保存自己的退出信息而无法释放所有资源成为僵尸进程导致资源泄露。
孤儿进程:父进程先于子进程退出,子进程成为孤儿进程,运行在后台,父进程成为1号进程(而孤儿进程的退出,会被1号进程负责任的进行处理,因此不会成为僵尸进程)
根据以上对两种特殊进程的理解分析选项:
- A选项正确,父进程退出后,所有子进程都会成为孤儿进程;
- B选项正确,僵尸进程的产生就是因为父进程没有对子进程的退出进行处理,因此子进程无法完全释放资源
- C选项正确,子进程成为孤儿进程后被1号进程收养,并且他们的退出状态由1号进程完成处理
- D选项错误,僵尸进程的产生会造成资源泄露需要避免,但是孤儿进程的产生一般都是具有目的性的,并且退出后并不会成为僵尸进程,因此无需特殊处理。
6.关于僵尸进程,以下描述正确的有?
A.僵尸进程必须使用waitpid/wait接口进行等待
B.僵尸进程最终会自动退出
C.僵尸进程可以被kill命令杀死
D.僵尸进程是因为父进程先于子进程退出而产生的
僵尸进程是指先于父进程退出的子进程程序已经不再运行,但是因为需要保存退出原因,因此资源没有完全释放的进程,
它不会自动退出释放所有资源,也不会被kill命令再次杀死
僵尸进程会产生资源泄露,需要避免
避免僵尸进程的产生采用进程等待(wait/waitpid)方式完成
根据以上理解分析:
- A选项正确,僵尸进程会造成资源泄露,必须使用wait/waitpid接口进行等待处理
- B选项错误,僵尸进程不会完全释放资源退出
- C选项错误,僵尸进程是已经退出运行的进程,无法被杀死
- D选项错误,僵尸进程是子进程先于父进程退出。