Linux中的进程
关于进程
进程的本质就是程序执行的过程,也就是程序的实体,本身没有什么可说的,但是要注意的是父进程和子进程,Linux程序在运行的过程中,会创建一个叫PCB的结构体,这种结构体中包含了一个进程中的各类详细信息,并会给这一个PCB获得一个编号,即PID,该编号的类型为pid_t,实质上就是int,就类似一个人出生后给他赋予的身份证号一样。在PCB中,不光包含了该进程的信息,也有其父进程的信息,即父进程的PID。
进程详解
实质上,一个进程就像一个活人一样,也是有家人,有生命的,家人其实就是父进程,生命就是其生命周期,下文展示各类进程的具体实现。
一般进程
想要在Linux中实现一个父进程和一个子进程,并查看其pid,此时就要用到fork()函数。
在Linux中,fork()函数可以创建一个子进程并返回pid,当返回值小于零的值时说明子进程创建失败,当返回值等于零时,表示现在正在处理子进程,当pid大于零时,表示正在处理父进程。
#include <stdio.h>
#include <unistd.h>
int main()
{
int i = 10;
pid_t ret = fork();
if(ret < 0)
{
printf("ret : %d\n", ret);
return -1;
}
else if(ret == 0)
{
//child
i += 10;
while(1)
{
printf("i am child , pid is : %d, i = %d\n",getpid(), i);
printf("my father is %d\n", getppid());
sleep(1);
}
}
else
{
//father
{
printf("i am father , pid is : %d, i = %d\n",getpid(), i);
printf("my father is %d\n", getppid());
sleep(20);
}
}
return 0;
}
其实现效果如下:
由此可以看出,父进程的pid为24695,子进程的pid为26892
孤儿进程
孤儿进程就像他的名字一样悲伤,指的是==父进程的生命结束,但是子进程还在执行,此时子进程就交给pid为1的init进程,这个进程是Linux初始化是系统第一个创建的进程,就像孤儿院一样接收各类孤儿进程。
其具体实现并不难,就是让父进程执行4秒后结束,让子进程执行10秒后结束,代码如下
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
pid_t pid;
pid = fork();
if(pid < 0)
{
printf("error!\n");
return -1;
}
if (pid == 0)
{
//child
int i = 10;
while(i)
{
printf("this is a child,pid = %d,my dad is %d\n",getpid(),getppid());
sleep(1);
i--;
}
printf("Now,child is dead!\n");
}
if (pid > 0)
{
//dad
int i = 4;
while(i)
{
printf("this is dad ,pid = %d,my dad is %d\n",getpid(),getppid());
sleep(1);
i--;
}
printf("Now,dad is dead!\n");
}
return 0;
}
具体实现效果如下图所示:
在图中可以看出,父进程的pid为14749,子进程的pid为14750,其中父进程的父进程的pid为6280,此时当父进程死亡后,子进程的父进程pid就自动为1,直到最后子进程也死亡。(挺悲伤的)
注意:这里需要注意的是,孤儿这一概念是人为创造的,但是纵观整个代码,子进程并没有真正成为孤儿,他只是换了个父进程,所以并不存在“孤儿状态”这一状态。
僵尸进程
僵尸进程和孤儿进程正好相反,指的是子进程死亡,但是父进程还在,此时父进程的PCB中还留有子进程的相关信息,尽管子进程已经死了,但是父进程还没注意到,对外输出的子进程信息是已经死去的子进程信息。
具体的代码实现如下:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
pid_t pid;
pid = fork();
if (pid < 0)
{
printf("fail\n");
return -1;
}
if (pid == 0)
{
//child
printf("this is a child,pid = %d\n",getpid());
sleep(1);
printf("child is dead\n");
}
else if (pid >0)
{
//dad
int i = 10;
while(i)
{
printf("this is dad,pid = %d,my son is %d\n",getpid(),pid);
sleep(1);
i--;
}
printf("dad is dead\n");
}
return 0;
}
实现效果如下图所示
可以看出,子进程的pid为10964,父进程的pid为10963,在中间的时候,child子进程已经死亡,但是还活着的父进程在执行的过程中还在对外输出子进程的信息,子进程就像是僵尸一样,没有了生命但是却“被活着”。
注意:和孤儿进程不同,僵尸进程是确实存在僵尸状态的