进程状态图解
运行 & 阻塞 & 挂起状态
运行态:就是可以理解为在调度队列中的进程的状态是运行态
阻塞态:等待某种资源就绪。如键盘,显示器,网卡等等。
把进程从调度队列上拿下来,放在设备调度队列中,等待资源,拿到资源后,再把该进程插到进程队列的队尾
阻塞挂起:当资源吃紧时,会把一时半会不会被调度阻塞资源的代码资源交换到磁盘当中,当要运行时,对应的代码资源就会被调出磁盘。
理解linux里面的链表
上面的Node是常规版本类型,加上pre,next,直接找上下一个结构体
下面的则是把pre和next封装成一个结构体,links,然后加到task_struct中去,通过links来查找上下一个结构体变量。
优点需要注意的是这种的找法:
结构体地址和结构体第一个成员的地址相等。
&((struct task_struct*)0->links),表示在当前结构体的偏离量,然后用list/next - 偏移量,就表示当前结构体的地址,再进行强转,就可以访问该结构体的任何数据了。
进程的几种状态
static const char * const task_state_array[] =
{
"R (running)", /* 0 */ "
S (sleeping)", /* 1 */ "
D (disk sleep)", /* 2 */ "
T (stopped)", /* 4 */ "
t (tracing stop)", /* 8 */ "
X (dead)", /* 16 */ "
Z (zombie)", /* 32 */
};
解读:
R:运行状态。 下标0
在运行队列里面。
./process & ----- 放在后台运行。
R+:表示在前台运行。S:sleeping,阻塞状态。 下标 1 可中断睡眠,浅睡眠
scanf,等待输入数据,就是等待状态T:stopped,暂停状态。 4
ctrl z:用户自主暂停。t:tracing,追踪。8
进程被暂停了。断点。D:disk sleep 2,深度睡眠,不可中断休眠。
当进程向磁盘传入数据的时候,操作系统无权杀掉它,只有等待进程自己结束才可以。
是一种高IO过程。
僵尸进程(Z)
子进程退出,父进程还在运行,但是父进程没有读取子进程返回的退出代码,那么子进程就会一直处在最终退出状态。
子进程就会一直处在僵尸状态。
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t id = fork();
if(id == 0)
{
//child
int count = 5;
while(count)
{
printf("我是子进程,我正在运行: %d\n", count);
sleep(1);
count--;
}
}
else
{
while(1)
{
printf("我是父进程,我正在运行...\n");
sleep(1);
}
}
// printf("我是一个进程, pid: %d\n", getpid());
int x;
scanf("%d", &x);
// while(1)
// {
// printf("hello bite\n");
// }
return 0;
}
Z状态危害?
进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎 么样了。
可父进程如果一直不读取,那子进程就一直处于Z状态?
是的!
维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话 说,Z状态一直不退出,PCB一直都要维护?
是的!
那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?
是的!
因为数据结构 对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空 间!
内存泄漏?
是的
那么如果进程退出了,内存泄漏还会不会存在?
不会存在。但有个别情况。
什么样的进程有内存泄漏的隐患?
常驻内存的进程如果发生内存泄露的话,就会出现内存泄漏的隐患。
孤儿进程 (X)
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
while(1)
{
sleep(1);
printf("我是一个父进程, pid: %d, ppid: %d\n", getpid(), getppid());
}
// pid_t id = fork();
// if(id == 0)
// {
// // child
// while(1)
// {
// printf("我是一个子进程, pid: %d, ppid: %d\n", getpid(), getppid());
// sleep(1);
// }
// }
// else
// {
// // father
// int cnt = 5;
// while(1)
// {
// printf("我是一个父进程, pid: %d, ppid: %d\n", getpid(), getppid());
// cnt--;
// sleep(1);
// }
// }
return 0;
}
孤儿进程:父进程提前退出,只剩下子进程
子进程要被1号进程领养,这个被领养的子进程被叫做孤儿进程。父进程的父进程是bash
1号进程是谁?
是“systemd”,操作系统的一部分。
可以理解为操作系统。为什么要领养?如果不领养的话,子进程会进入僵尸状态吗?
领养后会出现新的父进程,然后父进程会对子进程进行统一管理。ps jax | grep systemd