进程控制
进程组成
进程的组成:程序、数据和进程控制块
程序:描述进程所要完成的功能;
数据:提供运行所需的堆栈和私有数据;
进程控制块:包含进程的描述和控制信息,反映进程动态特性,是系统识别和控制进程的依据。
- 内核区(3GB - 4GB)
常驻系统内存,内部有进程控制块 - 用户区(0GB - 3GB)
包含:
(1)命令参数与环变量
(2)进程栈空间
(3)库空间(静态库与共享库)
(4)进程堆空间
(5)已初始化的全局资源
(6)未初始化的全局资源
(7)进程text带码段
进程原语
- 概述:进程使操作系统中的一个调度单位,系统为进程分配资源,进程完成待定的功能或任务,
- 分配:内存资源和CPU资源
注:程序与进程
程序为进程的静态表现,进程是程序的动态表现,编码结束编译可以执行的程序(exe m elf),执行程序系统为该程序创建一个进程,进程完成待定的任务 - 进程相关原语
(1)fork() 创建子进程
(2)exec() 进程功能重载(重载用户空间)
(3)wait() 进程同步
(4) waitpid()
进程控制块PCB
进程控制块:系统为每一个进程都创建一个PCB,用于描述进程信息与状态,如果进程没有PCB那他无法被内核识别与分配资源
进程之间的关系
Linux 的进程特性是强亲缘关系的进程(父子进程)
fork() 函数每调用一次都创建一个子进程
Linux 系统中的进程结构,主进程为 init (pid 1) ,其他所有进程都是init的子集
子进程创建的过程
- 父进程调用fork() 函数
- 内核调用创建子进程空间
- 子进程继承父进程可以继承的PCB中的数据
- 子进程完全拷贝父进程用户空间的数据
父进程代码执行
parent exec code : 父进程从起始位置开始执行代码,指导文件末尾
child exec code: 子进程从fork 开始执行(不创建1进程),直到文件末尾
fork 返回值
类型 pid_t
可以用来区分父子进程工作(为父子进程划分独立的工作区):工作区中的代码只有待定进程执行
fork函数调用一次有两个返回值,分别被父子进程接收
fork return value:父子进程pid , 子进程中返回0,出错返回 -1
Linux 系统函数的错误处理
Linux 下系统函数返回指针的 错误返回NULL(错误宏)
函数返回整形的失败返回-1
perror 返回时可以加上错误信息 ,打印系统默认全局变量ERRNO 中错误 对应错误表中的信息
可以自定义一个错误处理
void str_error(const char * errstr , int exitcode)
{
perror(errstr);
exit(exitcode);
}
父子资源共享
父子进程资源继承:父进程的资源数据会拷贝给子进程,子进程无需定义可以直接使用,使用修改也不会影响父进程资源
fork() 版本
- version 1.0 fork
初始版本的fork会将父进程资源大部分完整拷贝给子进程,内核空间资源拷贝是必须的,但是用户空间资源则不一定,用户空间为进程核心工作(任务数据)
缺点:如果拷贝给子进程,子进程未使用,那么这个拷贝开销毫无意义 - version 2.0 vfork
内核空间一定拷贝,用户空间不做处理 - version 3.0 fork
读时共享写时复制
exec() 进程功能重载
可以将任意进程中的功能区,替换给指定进程
exec(“程序的绝对路径” ,“程序名” , “程序参数” , NULL)
子进程通过exec获取丰富的功能,但是亲缘关系依然不变
当功能重载成功后,所有的数据被新功能替换,执行新功能代码,从新功能中结束或返回,与旧代码无关,旧代码不可以
需要子进程完成自定义任务,必须在fork之后,exec之前完成
进程状态
- 运行态:已经获取到系统资源,例如时间片资源,正在使用cpu,完成任务
- 就绪态:进程准备就绪,等待cpu资源,获取时间片资源立刻执行
- 阻塞态:进程因为某个系统调用或函数,进入阻塞或者睡眠态,立即放弃持有的cpu使用权限(阻塞可能被中断,无法完成任务获取结果)
- 挂起态:进程因为某个原因被挂起,立即放弃已经持有的cpu使用权,无法强制中断
特殊状态特殊进程
僵尸进程——僵尸态
子进程先于父进程结束,父进程没有回收子进程,导致内存泄漏,未被正确回收的子进程,linux系统成为僵尸态进程
僵尸进程的危害:
- pcb中成员较多,描述所有当前进程信息,还包含了一些地址成员(pcb内核栈信息)又占用额外的系统资源,所以pcb 如果泄漏残留浪废较大
- 系统按照pcb可用数量创建进程,僵尸进程占用一个pcb
wait() waitpid() 可用来回收僵尸进程
孤儿进程——孤儿态
父进程先于子进程终止,子进程处理托管状态
孤儿进程被托管进程,托管进程只负责回收僵尸pcb,不会干预子进程任务,如果该孤儿进程任务为(持续申请系统资源)系统负担较大,危害较大
守护进程
守护进程:与终端无关,常驻后台执行的特殊进程
注:前台进程:进程执行过程中始终占有终端的控制权,不能同时输入其它命令;
后台进程:进程不接管终端,必须是非交互式的。