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中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!

内存泄漏?是的!

相关推荐
电商API_180079052474 分钟前
自动化获取淘宝评论数据技术分享之API调用示例
大数据·运维·人工智能·自动化·网络爬虫
数智启示录4 分钟前
实时数据湖 flink CDC + Kafka +Doris 【企业级实战】性能调优与生产运维闭环 09
运维·flink·kafka
福建佰胜张工7 分钟前
西门子 ULTRAMAT23 分析仪 7MB2337‑0NH10‑3PW1 原理、调试、故障处理与现场运维全记录
大数据·运维·人工智能·自动化
啦啦啦啦啦zzzz8 分钟前
ET和LT详解
linux·运维·服务器·网络·c++·网络编程
田径他爸来了12 分钟前
嵌入式学习第32天(同时多个用户访问的服务器)
运维·服务器·学习
wefg114 分钟前
C++ 仿 muduo 库实现高并发服务器
运维·服务器
梦難22 分钟前
linux的系统命令
linux·服务器·网络
Java小白笔记23 分钟前
Java中PDF文件导出,生成链路与实现
服务器·网络·oracle
跨境技工小黎26 分钟前
YouTube联盟营销如何变现?如何利用IP代理提高流量变现效果?
服务器·网络·tcp/ip
高亦真38 分钟前
今天是学习嵌入式的第31天
linux·学习·算法