文章目录
1. PCB
1.1 PID
概念: 每一个进程都会有一个唯一的PID来标识这个进程
命令: top
功能: 可以查看进程的PID
1.2 进程状态
R:运行状态
S:可中断睡眠状态
D:不可中断睡眠状态
T:暂停状态
ctrl+z:使得一个进程变成暂停状态,暂停后进程任然是存在,不同于ctrl+c
t:跟踪状态
在gdb调试的时候会出现
X:死亡状态
Z:僵尸状态
1.3 程序计数器
保存了进程即将要运行的下一条指令
1.4 上下文信息
保存了寄存器当中的内容
1.5 内存指针
指向“程序地址空间”
1.6 记账信息
使cpu时长,占用内存大小
1.7 IO信息
保存了当前进程打开文件的信息
1.7.1 /proc
保存了当前操作系统维护的所有进程信息,每一个进程都是一个文件夹。
命令:
cd /proc
ls
标准输入:0
标准输出:1
标准错误:2
2. 进程创建
2.1 getpid()函数
获取当前进程的pid好,谁调用获取谁
2.2 getppid()函数
获取当前进程的父进程pid号
getpid()和getppid()函数是bash创建的
通过图中的内容可以看出第一行是父进程,父进程的pid是1870,ppid是14858,第二行是子进程,子进程的pid是1871,ppid是1870.
我们对14858这个进程进行查看,能得到这个进程实际上是我们的bash。
2.3 fork函数
可以让程序员在代码当中创建一个子进程
pid_t fork(void)
1.没有参数
2.pid_t 本质是整型
返回值:
失败:-1
成功:>0 返回给父进程
==0 返回给子进程
3.含义
4.原理:fork创建的子进程的PCB拷贝父进程的PCB
3. 僵尸进程&僵尸状态
3.1 创建一个main.c
命令: ps aux | grep main
功能: 查找名字有main的进程
通过进程状态的中的Z+可以说明进程22781是一个僵尸进程。
3.2 僵尸进程的产生由来
子进程先于父进程退出,子进程在退出的时候会告知父进程,但是父进程没有来得及回收子进程的资源,导致子进程的PCB没有被释放。
3.3 kill命令
命令: kill[pid]
命令: kill -9 [pid]
**功能:**结束进程
但是在这里通过kill是不能结束掉僵尸进程的。
3.4 危害
子进程的PCB没有办法得到释放,相当于内存泄露。
3.5 解决方案
1.重启操作系统,代价大,不推荐
2.杀掉僵尸进程的父进程,代价相对大,不推荐
3.进程等待-进程控制,推荐的方式
4. 孤儿进程
父进程先于子进程退出,子进程会被1号进程所领养,子进程在退出的时候,就会由1号进程回收子进程的退出资源,而子进程就不会变成僵尸进程,这样的进程称为孤儿进程。
1号进程是操作系统开机启动的第一个进程。没有孤儿状态,只有孤儿进程。
5.面试常见问题
问题一:请问创建出来的子进程是从fork之后代码运行还是从fork之前的代码开始运行?为什么?
因为代码在执行到第6行的时候父进程会创建一个子进程,同时也会将程序计数器和上下文信息记录中的数据也拷贝过去,子进程会从代码的第7行继续执行。
问题二:到底是父进程先运行还是子进程线运行?
这个是不确定的,取决于操作系统内核的调度和调度算法有关。