一、进程是什么?
进程是系统进行资源分配的基本单位,是一种逻辑单元,实际并不存在,是程序的动态表现。
二、进程状态
- 就绪态:进程已准备就绪,等待CPU分配准备运行。
- 阻塞态:放弃时间片(可使用seep(0)切换),可被强制中断。阻塞的进程资源在内存中,等待某一事件发生而暂停。
- 挂起态:放弃时间片,无法被强制中断,进程资源被交换到外存中。
- 运行态:进程得到的间片开始执行,时刻占用CPU。
- 终止态:进程结束退出,资源释放。
- 僵尸态:Linux独存,后面介绍。
- 孤儿态:Linux独存,后面介绍。
其中就绪态不能转为阻塞态和挂起态。
三、结构
进程一般被分配4G大小的内存空间,分为上下两层。
上层(1G)称为内核层(系统层),含有PCB(进程控制块,可理解为进程身份证)进程id称为pid,PCB是一个结构体,有384个进程信息
下层(3G)是用户层
PCB
PCB通常是通过链表的方式进行组织,把具有相同状态的进程链在一起,组成各种队列(就绪队列
和阻塞队列)
除了链接的组织方式,还有索引方式,它的工作原理:将同一状态的进程组织在一个索引表中,索引表项指向相应的 PCB,不同状态对应不同的索引表
内容:
进程描述信息:
进程标识符:标识各个进程,每个进程都有一个并且唯一的标识符;
用户标识符:进程归属的用户,用户标识符主要为共享和保护服务;
进程控制和管理信息:
进程当前状态,如 new、ready、running、waiting 或 blocked 等;
进程优先级:进程抢占 CPU 时的优先级
资源分配清单:
有关内存地址空间或虚拟地址空间的信息,所打开文件的列表和所使用的 I/O 设备信息
CPU 相关信息:
CPU 中各个寄存器的值,当进程被切换时,CPU 的状态信息都会被保存在相应的 PCB 中,以便进程重新执行时,能从断点处继续执行
函数
fork()
调用fork创建一个子进程,执行fork的为父进程
特点是被调用一次,返回两次。原因:子进程返回的是0(一个进程只能有一个父进程),父进程返回的是新建子进程的ID。
父进程从代码的起始位置执行到末尾,子进程从fork之后执行到未尾。父子共享栈帧,子进程读写指针位置向后迁移。子进程虽然也走了fork,但是只走了return0。ork之后先执行父还是先执行子不确定,看内核采用何种调度算法
vfork()
创建虚拟地址,并不将父进程的地址空间完全复制到子进程,因为子进程会立即调用exec。并保证子进程优先运行。
exit()
终止函数,等于执行return
wait()
wait函数是阻塞回收函数,它可以回收任意一个子进程,等待子进程结束后立即回收,每次回收一个僵尸进程。如果一个进程中有几个子进程,只要有一个子进程终止,wait就返回。
waitpid()
高级版回收函数:pid_t zpid = waitpid(pid t pid ,int * status,WNOHANG );
返回 > 0 表示回收成功,返回值为僵尸的pid
返回-1 表示回收失败
返回 0,表示当前子进程未结束,非阻塞返回0
可支持非阻塞回收
返回终止子进程的进程ID
与wait区别
- waitpid可等待一个特定进程,wait返回任意终止子进程状态
- 提供一个wait的非阻塞版本
- 通过WUNTRACED和WCONTINUED选项支持作业控制
总结
这就是我大概的理解,进程是系统进行资源分配的基本单位,非常重要!