【Linux】进程查看|fork函数|进程状态

news2024/11/16 23:30:41

🦄 个人主页——🎐开着拖拉机回家_Linux,大数据运维-CSDN博客 🎐✨🍁

🪁🍁🪁🍁🪁🍁🪁🍁 🪁🍁🪁🍁🪁🍁🪁 🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁🪁🍁

感谢点赞和关注 ,每天进步一点点!加油!

目录

一、基本概念

1.1 概念提出

1.2 特征

二、描述进程-PCB

2.1 什么是进程控制块PCB

2.2 task_struct内容分类(成员)

2.3 进程控制块如何对进程进行管理的呢?

三、查看进程

3.1 通过系统目录查看

3.2 通过用户级工具ps查看

四、通过系统调用获取进程标识符(PID)

4.1 使用getpid和getppid

五、通过系统调用创建进程-fork初识

5.1 fork函数

5.2 fork函数创建子进程

六、Linux进程状态

七、两种特殊进程

7.1 僵尸进程

7.2 孤儿进程


一、基本概念


1.1 概念提出


进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体(百度百科)。

1.2 特征


  • 动态性进程的实质是程序在多道程序系统中的一次执行过程,进程是动态产生,动态消亡的。
  • 并发性:任何进程都可以同其他进程一起并发执行
  • 独立性:进程是一个能独立运行的基本单位,同时也是系统分配资源和调度的独立单位;
  • 异步性由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进
  • 结构特征:进程由程序、数据和进程控制块三部分组成。

多个不同的进程可以包含相同的程序:一个程序在不同的数据集里就构成不同的进程,能得到不同的结果;但是执行过程中,程序不能发生改变。


二、描述进程-PCB


引入一个新概念: 进程控制块PCB(process control block)。PCB就是进程属性的集合(数据结构),里面存储的是进程信息。

2.1 什么是进程控制块PCB


进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合,称之为PCB(process control block),Linux操作系统下的PCB是: task_struct。

即task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含进程的信息。

2.2 task_struct内容分类(成员)


  • 标示符(PID): 描述本进程的唯一标示符,用来区别其他进程(每次启动都会变化)。
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级: 相对于其他进程的优先级。
  • 程序计数器(pc): 程序中即将被执行的下一条指令的地址。
  • 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
  • 上下文数据: 进程执行时处理器的寄存器中的数据。
  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
  • 记账信息: 可能包括处理器时间总和,使用的时钟总和,时间限制,记账号等。
  • 其他信息

2.3 进程控制块如何对进程进行管理


  • 磁盘中的可执行程序在将要运行时,所有的进程中的数据(并不是程序本身)加载到内存中,此时操作系统会建立起一个PCB来保存每一个程序的信息;
  • 这个时候PCB就会对每一个进程都建立起相应的结构体(即进程控制块)将对应的进程的属性、代码等匹配的传到这个结构体中:(这就是先描述)
  • 此时,操作系统就会将每一个进程控制块都连接起来,形成链表结构,并返回头结点。这样便通过数据结构的形式将进程的信息组织起来。

三、查看进程


3.1 通过系统目录查看


根目录下的proc目录,/proc下存储着进程信息。


目录名为数字的即为进程信息的目录,每个目录内存储着他们对应的进程信息。而这些数字对应着该进程的标识符PID。如下查看标识符PID=18964的进程信息:

我们进入进程 18964进程目录

3.2 通过用户级工具ps查看


实例:ps ajx/ps aux

该命令可以查看所有系统进程。如下查看PID=18964的进程信息

创建如下测试脚本并执行

#!/bin/bash
 
proc_test()
{
	while(true)
	do
		echo "I am a process!"
		sleep 1
	done
}

proc_test

## 执行
sh proc_test_18964.sh

另外通过指令对进程进行检测,检测它是否运行:

ps ajx | head -1 && ps ajx | grep  proc_test  | grep -v grep

这里grep实际也是进程,且该进程内包含有proc_test的信息,所以也显示出来了。-v选项是反向搜索的意思,即过滤掉包含有grep内容的信息。

  • PPID (Parent Process ID):代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • PID (Process ID): 代表这个进程的代号
  • PGID(Process Group):PGID就是进程所属的Group的Leader的PID,如果PGID=PID,那么该进程是Group Leader
  • SID(Session ID):和PGID非常相似,SID就是进程所属的Session Leader的PID,如果SID==PID,那么该进程是session leader
  • TPGID:终端进程组ID
  • STAT:进程状态

四、通过系统调用获取进程标识符(PID)


4.1 使用getpid和getppid


#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
	pid_t id = getpid();
	while (1)
	{
		printf("I am a process!pid:%d\n", id);
		sleep(1);
	}
	return 0;
}

执行上面可执行程序并运行如下命令进行监控

while :; do   ps ajx | head -1 && ps ajx | grep  proc_test  | grep -v grep ; sleep 1;done

函数getppid(获取父进程的进程标识符),一般在Linux中普通进程都有他的父进程。

每一个子进程都是由父进程创建出来的。

子进程只能有一个父进程,父进程可以有多个子进程。每次执行可执行程序,进程标识符会改变,因为每次都会创建新的进程。

编写如下测试代码

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
    pid_t id = getpid();
    pid_t fid = getppid();
    while (1)
    {
        printf("I am a process!pid:%d ppid:%d\n", id, fid);
        sleep(1);
    }
    return 0;
}

 执行结果如下图:

 多次执行我们发现程序多次执行子进程每次都会创建新的新的进程标识符,父进程标识符没有改变。如下父进程是bash命令行解释器。


五、通过系统调用创建进程-fork初识


5.1 fork函数


pid_t  fork(void);

 一个进程包括代码、数据和分配给进程的资源。fork 函数会新生成一个进程,调用 fork 函数的进程为父进程,新生成的进程为子进程。在父进程中返回子进程的 pid,在子进程中返回 0,失败返回-1。

5.2 fork函数创建子进程


创建测试代码: 

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
 
int main()
{
    pid_t pid;
	printf("before fork : pid is : %d, ppid is : %d\n", getpid(), getppid());
 
	pid=fork();
 
	printf("after fork : pid is : %d, ppid is : %d, fork return %d\n", getpid(), getppid(),pid);
	sleep(2);
	return 0;
}

编译后执行

fork函数执行后,后面的"after fork"执行了两次,8897作为父进程创建了子进程 8898。也就是说fork之后,代码共享,从一个进程分为两个分支,一为父,一为子。

进程调用fork,当控制转移到内核中的fork代码后,内核会:

  • 分配新的内存块和内核数据结构给子进程;
  • 将父进程部分数据结构内容拷贝至子进程;
  • 添加子进程到系统进程列表当中;
  • fork返回,开始调度器调度;

所以,fork之前父进程独立执行,fork之后父子两个执行流分别执行。注意:fork之后谁先执行完全由调度器决定。

fork它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:

(1) 在父进程中,fork返回新创建子进程的进程ID;

(2)在子进程中,fork返回0;

(3)如果出现错误,fork返回一个负值;

一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。


六、Linux进程状态


进程状态:

TASK_RUNNING:就绪/可运行状态

TASK_INTERRUPTABLE:进程被挂起(睡眠),直到等待条件为真被唤醒

TASK_UNINTERRUPTABLE:深度睡眠,睡眠期间不响应信号

TASK_STOPPED:进程的执行被暂停

TASK_TRACED:被其它进程跟踪,常用于调试

EXIT_ZOMBIE:僵死状态,进程的执行被终止

EXIT_DEAD:僵死撤销状态,防止wait类系统调用的竞争状态发送

可以使用man ps 查看进程状态 Ss、Sl、S+、Z、I 释义

具体解释如下:

  • D (TASK_UNINTERRUPTIBLE) 不可中断的睡眠状态
  • R (TASK_RUNNING) 正在运行,或在队列中的进程
  • S (TASK_INTERRUPTIBLE)     可中断的睡眠状态
  • T (TASK_STOPPED)    停止状态
  • t (TASK_TRACED) 被跟踪状态
  • Z (TASK_DEAD - EXIT_ZOMBIE) 退出状态,但没被父进程收尸,成为僵尸状态
  • W            进入内存交换(从内核2.6开始无效)
  • X (TASK_DEAD - EXIT_DEAD)   退出状态,进程即将被销毁
  • <    高优先级
  • N    低优先级
  • L    有些页被锁进内存
  • s    包含子进程
  • 位于前台的进程组;
  • l   多线程,克隆线程  multi-threaded (using CLONE_THREAD, like NPTL pthreads do)

七、两种特殊进程


7.1 僵尸进程


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

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

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

测试代码 :


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
    pid_t id = fork();
    if (id < 0) {
        perror("fork");
        return 1;
    }
    else if (id > 0) { //parent
        while(1)
        {
            printf("parent[%d] is sleeping...,ppid: %d\n", getpid(),getppid());
            sleep(1);
        }
    }
    else {
        printf("child[%d] is begin Z...,ppid: %d\n", getpid(),getppid());
        sleep(5);
        exit(1);
    }
    return 0;
}

fork函数执行后子进程PID:15156 在5 s后exit(1)异常退出 ,父进程15155没有读取到正常的退出代码导致产生僵尸进程。

进程PID:15156的名称加上了【】且后面跟着< defunct > (失效的)

7.2 孤儿进程


修改代码,让子进程和父进程同时不间断运行

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
	pid_t id = fork();
	if (id < 0) {
		perror("fork");
		return 1;
	}
	else if (id > 0) { //parent
             while(1)
             {
		printf("parent[%d] is sleeping...,ppid: %d\n", getpid(),getppid());
		sleep(1);
             }
	}
	else {
             while(1)
             {
		printf("child[%d] is begin Z...,ppid: %d\n", getpid(),getppid());
		sleep(1);
             }
	}
	return 0;
}

运行

while :; do ps ajx | head -1 && ps ajx | grep pro_test | grep -v grep ; sleep 1;done

监控进程状态

杀掉父进程(10552),子进程被编号为1的进程接管,该1号进程就是bash,而bash就是父进程的父进程,父进程被杀死后,bash进程就接管了子进程,这种失去“爸爸”后被接管的进程就被称为孤儿进程。且子进程从前台进程变成了后台进程。


原文链接:fork函数详解-CSDN博客

【Linux】进程周边001之进程概念-CSDN博客

fork()函数详解_fork函数-CSDN博客

原文链接:Linux进程状态_task_interrupt-CSDN博客

 

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

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

相关文章

Java日期工具类时间校验

Java日期工具类时间校验 嘚吧嘚正则表达式版本一版本二版本三 SimpleDateFormat工具类 嘚吧嘚 时间校验这个问题&#xff0c;我在网上找了很多资料&#xff0c;有用正则表达式的、有用格式工具类的。&#x1f928; 其实都能实现时间校验&#xff0c;既然两种方式都能实现&…

Vue3-25-路由-路由的基本使用

对路由的理解 路由 &#xff1a; 就是前端对页面路径的拦截&#xff0c;根据不同的路径渲染不同的组件&#xff0c; 从而实现单页应用中的页面局部刷新的功能。安装路由依赖 根据使用的不同的包管理工具采用不同的命令&#xff0c; 常见的三种包管理工具和对应的命令如下&…

Hex文件介绍及制作

Hex文件介绍 一、文件格式介绍数据格式Hex文件例子常见类型字段 二、CRC校验计算eg.地址文件CRC计算:020000040127D2:0200000400FFFB eg.数据文件计算 三、生成hex文件用Excel生成 一、文件格式介绍 Hex文件是一种十六进制文件格式&#xff0c;可由notpad打开或者HexView app打…

【Hive_05】企业调优1(资源配置、explain、join优化)

1、 计算资源配置1.1 Yarn资源配置1.2 MapReduce资源配置 2、 Explain查看执行计划&#xff08;重点&#xff09;2.1 Explain执行计划概述2.2 基本语法2.3 案例实操 3、分组聚合优化3.1 优化说明&#xff08;1&#xff09;map-side 聚合相关的参数 3.2 优化案例 4、join优化4.1…

vivado 快速到慢速时钟之间的多循环

快速到慢速时钟之间的多循环 在下面的场景中&#xff0c;启动时钟CLK1是快速时钟&#xff0c;捕获时钟CLK2是慢时钟。如下图所示。 在下一示例中&#xff0c;启动时钟CLK1是快速时钟。捕获时钟CLK2较慢时钟假设CLK1是CLK2的频率的三&#xff08;3&#xff09;倍。如下图所示。…

docker小白第七天

docker小白第七天 tomcat安装 docker hub上面查找tomcat镜像 点进tomcat&#xff0c;可以看到下载镜像的命令。但是因为文件太大&#xff0c;并且是国外下载镜像很慢&#xff0c;所以我们从前期配置好的阿里云镜像仓库下载。 docker search tomcat docker pull tomcatdocker…

后端主流框架-SpringMvc-day2

Java中的文件下载 2 文件下载 文件下载&#xff1a;就是将服务器&#xff08;表现在浏览器中&#xff09;中的资源下载&#xff08;复制&#xff09;到本地磁盘&#xff1b; 2.1 前台代码 前台使用超链接&#xff0c;超链接转到后台控制器&#xff0c;在控制器通过流的方式…

Intel FPGA 技术开放日

概要 时间&#xff1a;2023.11.14 全天 &#xff08; 9:00 - 16: 20&#xff09; 地点&#xff1a;北京望京. 凯悦酒店 主题内容&#xff1a;分享交流了Intel FPGA 产品技术优势和落地实践方案。 会议的议程 开场致词&#xff1a; FPGA业务&#xff0c;是几年前intel收购而…

虚拟环境和Pycharm中均有transforms仍报ModuleNotFoundError:No module named ‘transformers‘

问题&#xff1a;运行新模型&#xff0c;配置了新环境&#xff0c;下载了包后&#xff0c;仍然报ModuleNotFoundError&#xff1a;No module named transformers 错误。 查看Pycharm解释器&#xff1a; 没问题&#xff01;&#xff01;&#xff01;&#xff1f; 命令行查看虚…

Flink Job 执行流程

Flink On Yarn 模式 ​ 基于Yarn层面的架构类似 Spark on Yarn模式&#xff0c;都是由Client提交App到RM上面去运行&#xff0c;然后 RM分配第一个container去运行AM&#xff0c;然后由AM去负责资源的监督和管理。需要说明的是&#xff0c;Flink的Yarn模式更加类似Spark on Ya…

Hive安装笔记——备赛笔记——2024全国职业院校技能大赛“大数据应用开发”赛项——任务2:离线数据处理

将下发的ds_db01.sql数据库文件放置mysql中 12、编写Scala代码&#xff0c;使用Spark将MySQL的ds_db01库中表user_info的全量数据抽取到Hive的ods库中表user_info。字段名称、类型不变&#xff0c;同时添加静态分区&#xff0c;分区字段为etl_date&#xff0c;类型为String&am…

【电商项目实战】基于SpringBoot完成首页搭建

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《电商项目实战》。&#x1f3af;&#x1f3af; &am…

【PyQt学习篇 · ⑭】:QTableView的使用

文章目录 QTableView的使用示例 QTableView的使用 QTableView 是 PyQt 中用于显示表格数据的窗口部件&#xff0c;它提供了一个灵活的方式来显示和编辑数据。下面是一些关于 QTableView 的使用的具体信息&#xff1a; 创建 QTableView 对象&#xff1a; from PyQt5.QtWidgets …

计算机网络基础:OSI参考模型是什么?

一、概述 OSI (Open Systems Interconnection Model,开放式系统互联模型)&#xff0c;由ISO ( International Organization for Standardization&#xff0c;国际标准化组织 ) 收录在ISO 7489标准中并于1984年发布。 意义&#xff1a; 在OSI没有出来之前我们的网络有如下问题…

Linux Debian12使用podman安装upload-labs靶场环境

一、upload-labs简介 PHP语言编写&#xff0c;持续收集渗透测试和CTF中针对文件上传漏洞的靶场&#xff0c;总共21关&#xff0c;每一关都包含着不同的上传绕过方式。 二、安装podman环境 Linux Debian系统如果没有安装podman容器环境&#xff0c;可以参考这篇文章先安装pod…

如何在vscode当中预览html文件运行结果

如何在vscode当中预览html文件运行结果 下载拓展内容打开拓展界面下载拓展 运行html文件参考内容 上一篇文章当中讲了如何实现在网页上对html文件的预览,但是这样子其实在运行代码的过程当中效果比较差,那么还需要可以实时预览运行的结果 下载拓展内容 打开拓展界面 下载拓展 …

微信小程序发放红包封面及领取

微信小程序发放红包封面及领取 一、微信红包封面开放平台配置发放的红包封面二、小程序后管平台设置配置录入红包封面奖品信息三、微信小程序调用接口效果 一、微信红包封面开放平台配置发放的红包封面 微信红包封面开放平台 红包封面的发放方式有&#xff1a;领取二维码、领…

unity 保存和加载窗口布局

这么简单的事网上一堆废话文章 右上角&#xff0c;Layout点开后有保存和删除 要切换布局点红框里的已经保存的布局

Linux下MQTT环境的简单应用及搭建——之Mosquitto

文章目录 前言一、ubuntu搭建mqtt服务器 | 概要二、整体架构流程 | 技术实现细节1、下载源码2、安装Mosquitto3、解压并修改配置文件4、关于Mosquitto常见的一些操作指令5、启动mosquitto6、测试mosquitto测试1&#xff1a;Linux多终端交互测试测试2&#xff1a;Linux与Windows…

2023安洵杯-秦岭防御军wp

reverse 感觉有点点简单## import base64 def ba64_decode(str1_1):mapp "4KBbSzwWClkZ2gsr1qAQu0FtxOm6/iVcJHPY9GNp7EaRoDf8UvIjnL5MydTX3eh"data_1 [0] * 4flag_1 [0] * 3for i in range(32, 127):for y in range(32, 127):for k in range(32, 127):flag_1[0]…