Linux—进程状态

目录

一.前言

1.1.通过系统调用获取进程标示符

1.2.通过系统调用创建进程

二.进程状态

三.Z(zombie)-僵尸进程

四.僵尸进程危害


一.前言

学习进程的状态,我们首先了解一下进程的基本数据

1.1.通过系统调用获取进程标示符

由**getpid()**函数调用获取进程id

由**getppid()**函数调用获取父进程id

复制代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
printf("pid: %d\n", getpid());
printf("ppid: %d\n", getppid());
return 0;
}

1.2.通过系统调用创建进程

我们通过 fork()函数来创建进程

fork有俩个返回值(父进程返回创建子进程的进程ID;在子进程中,fork返回0,如果出现错误,返回负值 )

父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)

fork 之后通常要用 if 进行分流

复制代码
#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){ //child
printf("I am child : %d!, ret: %d\n", getpid(), ret);
}else{ //father
printf("I am father : %d!, ret: %d\n", getpid(), ret);
}
sleep(1);
return 0;
}

二.进程状态

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。

下面的状态在kernel源代码里定义:

复制代码
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
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运行状态(running) : 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠)

**D磁盘休眠状态(Disk sleep)**有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。

T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。

X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态

通过下面代码查看a.out 里面的进程状态

while :; do ps aux | grep a.out | grep -v grep ; sleep 2; echo "*****" ; done

三.Z(zombie)-僵尸进程

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程

僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。

所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

创建一个维持30秒的僵尸进程例子:

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
pid_t id = fork();
if(id < 0){
perror("fork");
return 1;
}
else if(id > 0){ //parent
printf("parent[%d] is sleeping...\n", getpid());
sleep(30);
}else{printf("child[%d] is begin Z...\n", getpid());
sleep(5);
exit(EXIT_SUCCESS);
}
return 0 ;
}

四.僵尸进程危害

进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!

维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说, Z状态一直不退出, PCB一直都要维护?是的!

那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!

内存泄漏?是的!

相关推荐
我也不曾来过11 分钟前
传输层协议UDP和TCP
linux·网络·udp
molihuan1 分钟前
最新VMware Ubuntu 1分钟极速安装 植物人教程
linux·ubuntu
拜托啦!狮子3 分钟前
安装EnsDb.Hsapiens.v86
java·服务器·前端
sdm07042712 分钟前
深刻理解进程信号
linux·运维·服务器
Simonhans16 分钟前
Linux安装Bun
linux·bun
数智化精益手记局24 分钟前
什么是安全生产?解读安全生产的基本方针与核心要求
大数据·运维·人工智能·安全·信息可视化·自动化·精益工程
70asunflower29 分钟前
Ubuntu `tree` 命令完全指南:让目录结构一目了然
linux·数据库·ubuntu
老四啊laosi29 分钟前
【Linux系统】16. 进程程序替换
linux·exec·程序替换
scheduleTTe31 分钟前
Nginx
服务器·前端·nginx
zjeweler34 分钟前
好淘云:低成本云服务器选型与实战应用指南
运维·服务器