进程状态 | 僵尸进程 | 孤儿进程 | 前台后台进程 | 守护进程

2024-02-08 04:04

本文主要是介绍进程状态 | 僵尸进程 | 孤儿进程 | 前台后台进程 | 守护进程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

        • 1.进程的三种基本状态
        • 2.Linux中进程状态查看
          • 2.1.进程检测脚本
          • 2.2.各种状态查看
        • 3.孤儿进程
        • 4.前台、后台、守护进程

1.进程的三种基本状态

进程的在系统当中是走走停停的,「运行 - 暂停 - 运行」的活动规律;进程在活动期间的三种状态:运行状态、就绪状态、阻塞状态

在这里插入图片描述

  • 运行状态(Running):该时刻进程占用 CPU;
  • 就绪状态(Ready):可运行,由于其他进程处于运行状态而暂时停止运行;
  • 阻塞状态(Blocked):该进程正在等待某一事件发生(或等待非CPU资源,如等待输入/输出IO操作的完成)而暂时停止运行,这时,即使给它CPU控制权,它也无法运行;

PCB是描述进程信息的结构体,它是通过链表的方式组织的。如果处于就绪状态的进程链在一起的是运行队列;而处于阻塞状态的进程链在一起的是阻塞队列!在Linux中,就绪和运行态都是R状态。来看看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 */
};
2.Linux中进程状态查看
2.1.进程检测脚本
while :; do ps axj | head -1 && ps axj | grep mytest;sleep 1;echo "------------------";done更加干净!
while :; do ps axj | head -1 && ps axj | grep mytest | grep -v grep;sleep 1;echo "------------------";done
2.2.各种状态查看

R运行状态(running): 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队里。测试代码:

#include <stdio.h>
#include <unistd.h>int main()
{while(true){printf("hello world\n");sleep(1);}return 0;
}

测试结果:R+后面的进程代表是一个前台进程

在这里插入图片描述

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

#include<stdio.h>
int main()    
{       int a = 0;    printf("请输入一个整数:");                                            scanf("%d",&a);    return 0;    
} 

测试结果:

在这里插入图片描述

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

可以使用dd命令来,测试dd命令在处理数据时非常强大,但同时也具有一定的风险性。如果使用不当,可能会导致数据丢失或损坏(建议是不用测试这个状态)

T停止状态(stopped): 可以通过发送 SIGSTOP (kill -19 pid)信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT(kill -18 pid) 信号让进程继续运行。**典型应用:调试!断点能停下来,是因为进程的T状态!**测试代码:

使用命令:kill -19 pid;将进程暂停

使用命令:kill -18 pid;将进程运行

#include <stdio.h>
#include <unistd.h>int main()
{while(true){printf("hello world\n");sleep(1);}return 0;
}

测试结果:

在这里插入图片描述

Z状态:僵尸(死)状态: 当子进程退出,但是父进程没调用waitwaitpid去获取子进程的状态信息,没有检测到子进程返回状态的代码时,子进程就会处于一个被检测的状态,就是僵尸状态。测试代码:

#include<stdio.h>
#include<unistd.h>int main()
{                pid_t ret = fork();if(ret < 0){perror("fork faile\n");return 1;}else if(ret == 0){int cnt = 5;while(cnt){printf("I am child pid = %d\n",getpid());cnt--;sleep(1);}}else    {      while(1)                                                               {    printf("I am father  pid = %d\n",getpid());    sleep(1);}    }    return 0;
}

测试结果:

在这里插入图片描述

僵尸进程的危害:子进程被创建出来,是为了完成父进程交给它的任务,父进程需要读取子进程的返回状态,但是父进程先退出,那么子进程就要一直维护Z状态;系统要一直维护子进程的PCB,那么就会造成内存泄漏。

父进程通过调用wait waitpid进程等待的方式解决僵尸进程问题。

3.孤儿进程

孤儿进程:父进程结束了,而它的一个或多个子进程还在运行,那么这些子进程就成为孤儿进程(father died)。子进程的资源由init进程(进程号PID = 1)回收。

测试代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{pid_t id = fork();if (id < 0){perror("fork");return 1;}else if (id == 0){printf("I am child, pid : %d\n", getpid());sleep(10);}else{ printf("I am parent, pid: %d\n", getpid());sleep(3);exit(0);}return 0;
}

测试结果:

在这里插入图片描述

4.前台、后台、守护进程

前台进程通常是用户正在交互的进程,本质是谁占有键盘资源谁就是前台进程!

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main()
{while(true){printf("hello world\n");sleep(1);}return 0;
}

启动前台进程:./mytest 或输入指令 启动后台进程:./mytest &,从下图可以看到我启动一个前台进程之后,通过键盘输入的 ll cd指令都不管用了。

在这里插入图片描述

启动后台进程:我们程序也在显示器上打印,但是输入的 ll cd 指令可以执行。

在这里插入图片描述

前台进程可以使用信号的方式终止,将程序启动为后台进程发现 ctrl + c 发送信号不能终止进程!使用jobs查看系统运行的任务 使用 fg + 任务号将后台进程转成前台进程,再通过 ctrl + c终止进程!

[xiyan@hecs-34711 ~]$ jobs
[1]+  Running                 ./mytest &  (wd: ~/code/test)
[xiyan@hecs-34711 ~]$ fg 1

任务和进程的关系(一个任务,可以一个人完成,也可多个人完成!)

一个任务可以是一个进程执行也可以是多个进程执行,多个进程组成进程组以第一个进程的进程pid为任务号,一个进程可以自成进程组!通过查看PGID属性字段就能验证。

[xiyan@hecs-34711 test]$ sleep 1000 | sleep 2000 | sleep 3000 &
[1] 6114
[xiyan@hecs-34711 test]$ mytest >> log.txt &
[2] 6141
[xiyan@hecs-34711 test]$ jobs
[1]-  Running                 sleep 1000 | sleep 2000 | sleep 3000 &
[2]+  Running                 ./mytest >> log.txt &
[xiyan@hecs-34711 test]$ ps axj | head -1 && ps xj | grep 'sleep'PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND4559  6112  6112  4559 pts/4     6267 S     1000   0:00 sleep 10004559  6113  6112  4559 pts/4     6267 S     1000   0:00 sleep 20004559  6114  6112  4559 pts/4     6267 S     1000   0:00 sleep 3000
[xiyan@hecs-34711 test]$ ps axj | head -1 && ps xj | grep 'mytest'PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND4559  6141  6141  4559 pts/4     6285 S     1000   0:00 ./mytest

会话的概念

在这里插入图片描述

Linux操作系统中,当一个用户登录的时候会分配一个会话,一个会话期间可以创建多个进程组,退出登录,会话会销毁;会话中前台进程终止,后台进程可能不会终止,但是会受一定的影响。

一个会话有多个进程,但是前台进程只有一个,系统会让bash来,充当前台进程,如果启动一个前台进程,就会将bash替换,当我们自己启动的前台进程退出,又将bash换上来!

退出登录后再登录 , 我的Linux机器是直接就终止了我们程序!如何解决——进程守护化

[xiyan@hecs-34711 test]$ ./mytest >> log.txt &
[1] 12130
[xiyan@hecs-34711 test]$ jobs
[1]+  Running                 ./mytest >> log.txt &
[xiyan@hecs-34711 test]$ ps axj | head -1 && ps axj | grep 'mytest'PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
12035 12130 12130 12035 pts/3    12153 S     1000   0:00 ./mytest
12035 12154 12153 12035 pts/3    12153 R+    1000   0:00 grep --color=auto mytest
[xiyan@hecs-34711 ~]$ ps axj | head -1 && ps axj | grep 'mytest'PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
12181 12214 12213 12181 pts/3    12213 R+    1000   0:00 grep --color=auto mytest

什么是守护进程

将自成进程组自成会话的进程,称为守护进程,他的本质也是孤儿进程;

让会话1创建一个守护进程,当会话1退出守护进程不受影响!

在这里插入图片描述

[xiyan@hecs-34711 ~]$ man 2 setsid
[xiyan@hecs-34711 ~]$ man daemon	# 系统自带的方法

参考代码:

#pragma once#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>const std::string nullfile = "/dev/null";void Daemon(const std::string &cwd = "")
{// 1. 忽略其他异常信号signal(SIGCLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);signal(SIGSTOP, SIG_IGN);// 2. 将自己变成独立的会话if (fork() > 0)exit(0);setsid();// 3. 更改当前调用进程的工作目录if (!cwd.empty())chdir(cwd.c_str());// 4. 标准输入,标准输出,标准错误重定向至/dev/nullint fd = open(nullfile.c_str(), O_RDWR);if(fd > 0){dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);close(fd);}
}

这篇关于进程状态 | 僵尸进程 | 孤儿进程 | 前台后台进程 | 守护进程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/689845

相关文章

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

一文解密Python进行监控进程的黑科技

《一文解密Python进行监控进程的黑科技》在计算机系统管理和应用性能优化中,监控进程的CPU、内存和IO使用率是非常重要的任务,下面我们就来讲讲如何Python写一个简单使用的监控进程的工具吧... 目录准备工作监控CPU使用率监控内存使用率监控IO使用率小工具代码整合在计算机系统管理和应用性能优化中,监

Linux进程CPU绑定优化与实践过程

《Linux进程CPU绑定优化与实践过程》Linux支持进程绑定至特定CPU核心,通过sched_setaffinity系统调用和taskset工具实现,优化缓存效率与上下文切换,提升多核计算性能,适... 目录1. 多核处理器及并行计算概念1.1 多核处理器架构概述1.2 并行计算的含义及重要性1.3 并

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

Windows的CMD窗口如何查看并杀死nginx进程

《Windows的CMD窗口如何查看并杀死nginx进程》:本文主要介绍Windows的CMD窗口如何查看并杀死nginx进程问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows的CMD窗口查看并杀死nginx进程开启nginx查看nginx进程停止nginx服务

Java进程CPU使用率过高排查步骤详细讲解

《Java进程CPU使用率过高排查步骤详细讲解》:本文主要介绍Java进程CPU使用率过高排查的相关资料,针对Java进程CPU使用率高的问题,我们可以遵循以下步骤进行排查和优化,文中通过代码介绍... 目录前言一、初步定位问题1.1 确认进程状态1.2 确定Java进程ID1.3 快速生成线程堆栈二、分析

IIS 7.0 及更高版本中的 FTP 状态代码

《IIS7.0及更高版本中的FTP状态代码》本文介绍IIS7.0中的FTP状态代码,方便大家在使用iis中发现ftp的问题... 简介尝试使用 FTP 访问运行 Internet Information Services (IIS) 7.0 或更高版本的服务器上的内容时,IIS 将返回指示响应状态的数字代