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

文章目录

        • 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);
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

还得是它!GPT4.0和MJ都搞定了!SD也快了!

之前给大家分享过一个国内的AI镜像平台——葫芦AI&#xff0c;目前接入了Midjourney和DALL3、GPT4.0和文心一言4.0。 前几天夜里1点多这个葫芦AI台平‬升级了GPT4接口和资料库&#xff0c;立试马‬用了‬一下&#xff0c;很‬不错。接口‬能力和官‬方差‬不多。后面能把Gpts和…

新增C++max函数的使用

在 C 中&#xff0c;max函数是标准库中的一个函数&#xff0c;用于返回两个或多个元素中的最大值。max函数的声明如下&#xff1a; cpp #include <algorithm>template<class T> const T& max(const T& a, const T& b);这个函数接受两个同类型的参数a…

部署一个在线OCR工具

效果 安装 1.拉取镜像 # 从 dockerhub pull docker pull mmmz/trwebocr:latest 2.运行容器 # 运行镜像 docker run -itd --rm -p 10058:8089 --name trwebocr mmmz/trwebocr:latest 使用 打开浏览器输入 http://192.168.168.110:10058/ 愉快滴使用吧

【开源】基于JAVA+Vue+SpringBoot的贫困地区人口信息管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 人口信息管理模块2.2 精准扶贫管理模块2.3 特殊群体管理模块2.4 案件信息管理模块2.5 物资补助模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 人口表3.2.2 扶贫表3.2.3 特殊群体表3.2.4 案件表3.2.5 物资补助表 四…

肯尼斯·里科《C和指针》第12章 使用结构和指针(2)双链表

12.3 双链表 单链表的替代方案就是双链表。在一个双链表中&#xff0c;每个节点都包含两个指针——指向前一个节点的指针和指向后一个节点的指针。这可以使我们以任何方向遍历双链表&#xff0c;甚至可以随意在双链表中访问。下面的图展示了一个双链表。 下面是节点类型的声明&…

为什么大模型需要向量数据库?

AIGC 时代万物都可以向量化&#xff0c;向量化是 LLM 大模型以及 Agent 应用的基础。 比如&#xff1a;爆火的 Google 大模型 Gemini 1.0 原生支持的多模态&#xff0c;在预训练的时候就是把文本、图片、音频、视频等多模态先进行 token 化&#xff0c;然后构建一维的“语言”…

Powershell Install 一键部署Openssl+certificate证书创建

前言 Openssl 是一个方便的实用程序,用于创建自签名证书。您可以在所有操作系统(如 Windows、MAC 和 Linux 版本)上使用 OpenSSL。 Windows openssl 下载 前提条件 开启wmi,配置网卡,参考 自签名证书 创建我们自己的根 CA 证书和 CA 私钥(我们自己充当 CA)创建服务器…

数据结构第九天(堆排序)

目录 前言 概述 源码&#xff1a; 主函数&#xff1a; 运行结果&#xff1a; 其他 前言 哈哈&#xff0c;这个堆排序算法很久之前就已经敲过一遍了&#xff0c;时间一久&#xff0c;思路有点淡忘。今天重新看过一遍之后&#xff0c;又亲自撸代码&#xff0c;幸运的是&am…

【RL】Bellman Equation (贝尔曼等式)

Lecture2: Bellman Equation State value 考虑grid-world的单步过程&#xff1a; S t → A t R t 1 , S t 1 S_t \xrightarrow[]{A_t} R_{t 1}, S_{t 1} St​At​ ​Rt1​,St1​ t t t, t 1 t 1 t1&#xff1a;时间戳 S t S_t St​&#xff1a;时间 t t t时所处的sta…

C++ | vector二维数组的初始化与行、列数的获取

如果直接使用vector<int,vector<int> > v;创建二维数组&#xff0c;那么就会得到一个空的容器&#xff0c;这样再通过push_back赋值是非常麻烦的。 初始化二维数组 在此介绍二维数组初始化的一般操作。 首先看一维数组的初始化示例&#xff1a; 定义一个长度为n&a…

拿捏循环链表

目录&#xff1a; 一&#xff1a;单链表&#xff08;不带头单向不循环&#xff09;与循环链表&#xff08;带头双向循环&#xff09;区别 二&#xff1a;循环链表初始化 三&#xff1a;循环链表头插 四&#xff1a;循环链表尾插 五&#xff1a;循环链表头删 六&#xff1…

MessageBox好用吗?

MessageBox作为一种能够对接多系统平台的工具&#xff0c;在数字营销领域具有很大的实用性和价值。它提供了实时的数据同步、个性化的营销策略、用户互动功能等多种功能&#xff0c;可以帮助企业实现更精准、高效的营销活动。具体来说&#xff0c;MessageBox的优点包括&#xf…

Laykefu客服系统后台登录绕过

【产品介绍】 Laykefu 是一款基于workermangatawayworkerthinkphp5搭建的全功能webim客服系统&#xff0c;旨在帮助企业有效管理和提供优质的客户服务 【漏洞介绍】 请求头中Cookie中的”user_name“不为空时即可绕过登录系统后台&#xff0c;恶意攻击者可利用此漏洞获得后台…

基于摄像头的虹膜识别技术

随着苹果公司的指纹识别TouchID的推广流行&#xff0c;三星等公司的积极跟进&#xff0c;生物识别技术正被移动设备厂商所重视。 虹膜是什么&#xff1f; 人的眼睛由巩膜、虹膜、瞳孔三部分构成。巩膜即眼球外围的白色部分&#xff0c;约占总面积的30%&#xff1b;眼睛中心为瞳…

【React】如何使antd禁用状态的表单输入组件响应点击事件?

最近遇到一个需求&#xff0c;需要在<Input.textarea>组件中&#xff0c;设置属性disabled为true&#xff0c;使textarea响应点击事件&#xff0c;但直接绑定onClick并不会在禁用状态下被响应。 解决方法1 之后尝试了很多方法&#xff0c;比如设置csspointer-events:no…

日本失去的三十年:去杠杆用了14年

去年以来&#xff0c;日股在日本央行转鹰预期、基本面改善和一系列监管新规的催化下高歌猛进&#xff0c;日经指数已经逼近90年代资产泡沫时期的高位。今年迄今累计上涨8.51%&#xff0c;领跑全球&#xff0c;“失落的三十年”似乎已经远去。 日本因何走向衰退&#xff1f;“失…

MPLS VPN功能组件(2)

MP-BGP 采用地址族(Address Family)来区分不同的网络层协议,以便正确处理VPN-IPv4路由 传统的BGP-4(RFC1771)只能管理IPv4的路由信息,无法正确处理地址空间重叠的VPN的路由。 为了正确处理VPN路由,VPN使用RFC2858(Multiprotocol Extensions for BGP-4)中规定的MP-BG…

云计算 - 弹性计算技术全解与实践

一、引言 在过去的十年里&#xff0c;云计算从一个前沿概念发展为企业和开发者的必备工具。传统的计算模型通常局限于单一的、物理的位置和有限的资源&#xff0c;而云计算则通过分布式的资源和服务&#xff0c;为计算能力带来了前所未有的"弹性"。 弹性&#xff1a;…

TryHackMe-Vulnerability Capstone练习

本文相关的TryHackMe实验房间链接&#xff1a;TryHackMe | Vulnerability Capstone 先nmap扫一下 接下来我们访问一下 接下来我们searchsploit找一下漏洞 searchsploit Fuel CMS 执行漏洞exp&#xff08;此处使用TryHackMe中的box&#xff09; 如果使用本地机需要下载exp&am…

算法练习-删除二叉搜索树中的节点(思路+流程图+代码)

难度参考 难度&#xff1a;中等 分类&#xff1a;二叉树 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。且所在课程未提供测试平台&#xff0c;故实现代码主要为自行测试的那种&#xff0c;以下内容均为个人笔记&#xff0c;旨…