1.什么是进程?
进程就是程序的一个执行实例,比如一个正在执行的程序。实际上是是一个分配系统资源(cpu,内存)的实体。进程的信息被存放于一个进程控制块(PCB)的数据结构中,Linux下的PCB是task_struct。task_struct是Linux系统中的一种数据结构,他会被装载到内存中,并包含着进程的信息。所有运行在系统中的进程都是以task_struct链表形式存在于内核中。
task_struct中存在
标识符:用来描述进程,区别于其他进程,唯一
状态:任务状态,退出码,退出信号等
优先级:相比较与其他进程的优先级
程序计数器:记录着下一条将要被执行的指令的地址
内存指针:程序代码和进程相关数据的指针还有其他进程共享内存块的指针
上下文数据:进程执行时处理器中的寄存器的数据
IO状态信息:包括IO请求,分配给IO设备和被使用的文件列表
其他信息
Linux下可以通过/proc查看进程信息
进程id:pid
父进程id:ppid
通过代码查看进程id
可以调用getpid()和getppid()函数查看进程和父进程id
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
printf("pid:%d",getpid());
printf("ppid:%d",getppid());
return 0;
}
2.通过系统调用创建一个进程
调用fork()函数可以创建一个子进程
fork()函数有两个返回值,子进程的返回值等于0,父进程的返回值大于0.。若返回值小于0,则创建进程失败。
下面通过代码来实现一下
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int ret=fork();
if(ret<0)
{
perror("fork");
return -1;
}
else if(ret==0)
{
printf("i am child:%d,ret:%d\n",getpid(),ret);
}
else if(ret>0)
{
printf("i am father:%d,ret:%d\n",getppid,ret);
}
return 0;
}
3.进程状态
一个进程在不同的时间可以有不同的状态,它们分别是
R(运行状态):并不意味这进程一定正在运行,也可能在运行队列中
S(睡眠状态):意味着进程正在等待事件完成
D(磁盘休眠状态):也可以叫做不可中断的睡眠状态,通常此状态下进程会等待IO结束
T(停止状态):可以发送SIGSTOP信号停止,这个被暂停的进程可以发送SIGCONT信号让他继续运行
X(死亡状态):这个状态为一个返回状态,你不会在任务列表里看见这个状态
4.僵尸进程
什么是僵尸进程?
当一个进程死亡并退出,但是父进程并没有获取到他的返回代码,这个进程就会变成僵尸进程,僵尸进程会一直以终止状态保持在进程表里并会一直等待父进程获取其退出状态。所以只要子进程退出,父进程还在运行,但父进程没有读取子进程的进程状态,子进程进入Z状态。那么如果父进程退出了呢?它就会变成孤儿进程,被init进程回收
一段代码来展示一个僵尸进程
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
pid_t pid=fork();
if(pid<0)
{
perror("fork");
return -1;
}
else if(pid==0)
{
printf("i am chlid\n");
exit(0);
}
else if(pid>0)
{
while(1)
{
printf("i can hear anything\n");
sleep(1);
}
}
}
这样便产生了一个僵尸进程可以通过指令ps -l查看其状态
pid为8953的进程状态为z。僵尸进程会一直占用着系统资源,造成资源浪费。并且不会被kill -9 杀死,那么我们如何 释放他呢?
可以通过杀掉他的父进程pid为8952的进程,指令kill -9 8952后僵尸进程父进程退出被init进程回收。