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

news2024/9/26 21:41:47

文章目录

        • 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 COMMAND
 4559  6112  6112  4559 pts/4     6267 S     1000   0:00 sleep 1000
 4559  6113  6112  4559 pts/4     6267 S     1000   0:00 sleep 2000
 4559  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 COMMAND
 4559  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/null
    int fd = open(nullfile.c_str(), O_RDWR);
    if(fd > 0)
    {
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        close(fd);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1438693.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《计算机网络简易速速上手小册》第7章:云计算与网络服务(2024 最新版)

文章目录 7.1 云服务模型&#xff08;IaaS, PaaS, SaaS&#xff09;- 你的技术魔法盒7.1.1 基础知识7.1.2 重点案例&#xff1a;构建和部署 Python Web 应用实现步骤具体操作步骤1&#xff1a;创建 Flask Web 应用步骤2&#xff1a;准备应用部署 7.1.3 拓展案例1&#xff1a;使…

transformer剪枝论文汇总

文章目录 NN Pruning摘要实验 大模型剪枝LLM-PrunerSparseGPT LTPVTPWidth & Depth PruningPatch SlimmingDynamicViTSPViTDynamicBERTViT SlimmingFastFormersNViTUVCPost-training pruning NN Pruning 《Block Pruning For Faster Transformers》 《为更快的transformer…

MPC |模型预测控制的一些基本概念

模型预测控制就是在每个采样点处&#xff0c;根据被控对象的状态和预测模型&#xff0c;预测系统在未来一段时间内的状态&#xff0c;依据某一性能指标&#xff08;成本函数&#xff09;来求解最优的一组控制序列&#xff0c;并将这组控制序列的第一个控制作用作为输出给执行机…

【数据库】Unlogged 表使用

【数据库】Unlogged 表使用 前言普通表和Unlogged 表的写性能比较普通表创建和数据插入Unlogged 表创建和数据插入比较结果 Unlogged 表崩溃和正常关闭测试Unlogged 表特点总结 前言 大神偶像在开会上提及了Unlogged 表&#xff0c;它的特点很不错&#xff0c;很适合实时数据保…

顺序表、链表相关OJ题(2)

创作不易&#xff0c;友友们给个三连吧&#xff01;&#xff01; 一、旋转数组&#xff08;力扣&#xff09; 经典算法OJ题&#xff1a;旋转数组 思路1&#xff1a;每次挪动1位&#xff0c;右旋k次 时间复杂度&#xff1a;o(N^2) 右旋最好情况&#xff1a;k是n的倍数…

寒假作业5

TCP 1&#xff1a;提供面向连接的&#xff0c;可靠的数据传输服务 2&#xff1a;传输过程中&#xff0c;数据无误、数据无丢失、数据无失序、数据无重复 3&#xff1a;数据传输效率低&#xff0c;耗费资源多 4&#xff1a;数据收发是不同步的 5&#xff1a;TCP的使用场景&#…

Mysql大表添加字段失败解决方案

背景 最近遇到一个问题&#xff0c;需要在user用户表千万级别数据中添加两个字段&#xff0c;发现老是加不上去&#xff0c;一直卡死。表数据量不仅大&#xff0c;而且是一个热点表&#xff0c;访问频率特别高&#xff0c;而且该表的访问是在一个大事务中。加字段的时候一直在…

基于SpringBoot的美妆管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

手撕spring bean的加载过程

这里我们采用手撕源码的方式&#xff0c;开始探索spring boot源码中最有意思的部分-bean的生命周期&#xff0c;也可以通过其中的原理理解很多面试以及工作中偶发遇到的问题。 springboot基于约定大于配置的思想对spring进行优化&#xff0c;使得这个框架变得更加轻量化&#…

【从Python基础到深度学习】1. 安装Python PyCharm

前言&#xff1a; 为了帮助大家快速入门机器学习-深度学习&#xff0c;从今天起我将用100天的时间将大学本科期间的所学所想分享给大家&#xff0c;和大家共同进步。【从Python基础到深度学习】系列博客中我将从python基础开始通过知识和代码实践结合的方式进行知识的分享和记…

Apollo分布式配置中心

携程框架部门研发的开源配置管理中心&#xff0c;能够集中化管理应用不同环境、不同集群的配置&#xff0c;配置修改后能够实时推送到应用端 用户在配置中心对配置进行修改并发布配置中心通知Apollo客户端有配置更新Apollo客户端从配置中心拉取最新的配置、更新本地配置并通知…

网络安全挑战:威胁建模的应对策略与实践

在数字威胁不断演变的时代&#xff0c;了解和降低网络安全风险对各种规模的组织都至关重要。威胁建模作为安全领域的一个关键流程&#xff0c;提供了一种识别、评估和应对潜在安全威胁的结构化方法。本文将深入探讨威胁建模的复杂性&#xff0c;探索其机制、方法、实际应用、优…

基于高通滤波器的ECG信号滤波及心率统计matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 ECG信号简介 4.2 高通滤波器原理 4.3 心率统计 5.完整工程文件 1.课题概述 通过高通滤波器对ECG信号进行滤波&#xff0c;然后再统计其心率。 2.系统仿真结果 3.核心程序与模型 版本&#xff1a…

Arm发布新的人工智能Cortex-M处理器

Arm发布了一款新的Cortex-M处理器&#xff0c;旨在为资源受限的物联网&#xff08;IoT&#xff09;设备提供先进的人工智能功能。这款新的Cortex-M52声称是最小的、面积和成本效率最高的处理器&#xff0c;采用了Arm Helium技术&#xff0c;使开发者能够在单一工具链上使用简化…

巴尔加瓦算法图解:算法运用。

树 如果能将用户名插入到数组的正确位置就好了&#xff0c;这样就无需在插入后再排序。为此&#xff0c;有人设计了一种名为二叉查找树(binary search tree)的数据结构。 每个node的children 都不大于两个。对于其中的每个节点&#xff0c;左子节点的值都比它小&#xff0c;…

ChatGPT高效提问—prompt常见用法

ChatGPT高效提问—prompt常见用法 1.1 角色扮演 ​ prompt最为常见的用法是ChatGPT进行角色扮演。通常我们在和ChatGPT对话时&#xff0c;最常用的方式是一问一答&#xff0c;把ChatGPT当作一个单纯的“陪聊者”。而当我们通过prompt为ChatGPT赋予角色属性后&#xff0c;即使…

debian12 - openssh-9.6.P1的编译安装

文章目录 debian12 - openssh-9.6.P1的编译安装概述笔记备注END debian12 - openssh-9.6.P1的编译安装 概述 在debian12上, 源码编译安装了openssl3.2 导致ssh失败. lostspeeddebian12d4x64:~$ openssl version OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2…

ywtool inspect命令

一.巡检介绍 日巡检是通过定时任务每天凌晨2点30进行巡检周巡检时通过定时任务每周日的凌晨3点进行巡检日巡检日志文件路径:/usr/local/ywtools/log/daily,每周日凌晨2点会将这一周的日巡检日志进行压缩,压缩路径:/usr/local/ywtools/log/backup/daily周巡检日志文件路径:/usr…

Docker-Learn(一)使用Dockerfile创建Docker镜像

1.创建并运行容器 编写Dockerfile&#xff0c;文件名字就是为Dockerfile 在自己的工作工作空间当中新建文件&#xff0c;名字为Docerfile vim Dockerfile写入以下内容&#xff1a; # 使用一个基础镜像 FROM ubuntu:latest # 设置工作目录 WORKDIR /app # 复制当前目…

消息中间件之RocketMQ源码分析(八)

RocketMQ中的消息过滤 RocketMQ设计了消息过滤&#xff0c;来解决大量无意义流量的传输:即对于客户端不需要的消息&#xff0c; Broker就不会传输给客户端&#xff0c;以免浪费宽带&#xff0c;RocketMQ4.2.0支持Tag过滤、SQL92过滤、Filter Server过滤 Tag过滤 第一步:用户发…