Linux进程

2023-11-02

进程基本概念

书上的概念是,进程是程序的一个执行实例,正在执行的程序等。在内核的观点看,进程是承担分配系统资源(CPU时间,内存)的实体

描述进程PCB

OS为了管理进程,将进程信息描述出来,放在一个数据结构中,可以理解为进程属性的集合。这个数据结构称为PCB(process control block),Linux操作系统下的PCB是: task_struct,task_struct是Linux内核的一种数据结构,是一个结构体。它会被装载到RAM(内存)里,task_struct中几乎包含了进程相关的所有属性信息。
在这里插入图片描述

操作系统将所有的进程控制块(task_struct)用双链表的形式组织链接起来。OS对进程的管理,转化成为了对进程信息的管理,先描述再组织。在内核里面将对进程的管理变为对双链表的增删查改。

task_ struct内容分类

1.标识符:描述本进程的唯一标示符,用来区别其他进程。
Linux中用pid来标识进程,每一个进程在运行起来后都有一个唯一的标识,就是pid。
在这里插入图片描述
2.状态:任务状态,退出代码,退出信号等。
3.优先级: 相对于其他进程的优先级。优先级本质是在资源有限的前提下,确立谁先访问资源,谁后访问资源的问题。
4.程序计数器: 程序中即将被执行的下一条指令的地址。
CPU的核心工作流程可以简单理解为:
a.取指令 b.分析指令 c.执行指令
CPU运行的代码都是进程的代码,它怎样知道取进程中的哪些指令?
在cpu中有一个eip寄存器,这个寄存器会保存当前正在执行指令的下一条指令的地址。这个寄存器通常称为PC指针。当进程不运行了,但是它没有跑完的时候,将eip里面的内容保存进pcb里。
5.内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。可以通过内存指针找到该进程相关的代码和数据。
6.上下文数据:进程在CPU上运行,CPU寄存器上会有很多临时数据,当进程运行完毕从cpu上剥离的时候,这些数据是需要被保存的,这些数据称为当前进程的上下文数据。
7.I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
8.记账信息:包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。

通过系统调用创建进程-fork

在linux中使用fork函数创建子进程。
在这里插入图片描述
pid_t是ProcessID_Type的缩写,其实是宏定义的unsigned int类型。
在这里插入图片描述
fork返回值如果子进程创建成功给子进程返回0,父进程返回子进程pid,如果失败了给父进程返回-1。
从程序员的角度看fork之后父子进程共享用户代码,而用户数据各自私有一份。因为代码是只读的,不可以修改或写入,本质上是为了维护进程的独立性。
从操作系统角度看多了一个进程,多了一个内核数据结构task_struct,创建子进程,通常以父进程为模板。其中子进程默认使用父进程的代码和数据(写时拷贝)。

#include<stdio.h>
#include<unistd.h>

int main()
{
	printf("i am father: %d\n", getpid());
	pid_t ret = fork();
	if(ret == 0)
	{
		//child
		while(1)
		{
			printf("i am child, pid:%d, ppid:%d\n", getpid(), getppid());
			sleep(1);
		}
	}
	else if(ret > 0)
	{
		//father
		while(1)
		{
			printf("i am father, pid:%d, ppid:%d\n", getpid(), getppid());
			sleep(1);
		}
	}
	else
	{
		//出错
	}
	return 0;
}

在这里插入图片描述
可以通过getpid()函数查看进程pid,getppid()查看该进程父进程的pid。

进程状态

/*
* 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): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。
D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。

S状态和D状态对比:
S状态称为休眠状态,这种状态是浅度休眠,大部分的情况都属于浅度休眠。所谓浅度休眠指的是这种状态是可以被唤醒的。它虽然是一种休眠状态,但是随时可以接收外部的信号,处理外部的请求(通知它处理,它会在一瞬间醒来处理请求),换句话说,浅度休眠可以对外部事件做出反应。
D状态是深度休眠,深度休眠的进程不可被杀掉,即便是操作系统也不行。D状态通常在访问磁盘这样的IO设备,进行数据拷贝的关键步骤上需要将进程设置为D状态。D状态什么时候结束呢?只能等D状态的进程自动醒来,或者是关机重启(甚至重启都有可能导致机器被夯住)。
不管是深度休眠还是浅度休眠本质上都是一种等待状态。

T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
t (tracing stop):进程在gdb调试的时候可能看到这个状态。

Z(zombie)-僵尸进程

进程退出的时候,会自动将自己退出时的相关信息写入进程的PCB中,供OS或者父进程读取。读取成功之后,该进程才算真正死亡(X状态)。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵尸进程(Z状态)。
僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程就进入Z状态。
D状态和Z状态发送9号信号kill不掉,因为一个是在深度休眠,一个已经挂掉了。
僵尸进程的危害
维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB就要一直维护。
一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费,导致内存泄露。

孤儿进程

#include<stdio.h>
#include<stdlib.h>                                                                                        
#include<unistd.h>

int main()
{
	if(fork() > 0)
	{
		sleep(5);                                                                                         
		printf("i am father,pid:%d i quit!\n", getpid());
		exit(0);
	}
	while(1)
	{                                                                                                     
		printf("i am child, pid:%d, ppid:%d\n", getpid(), getppid());
		sleep(1);
	}
	return 0;
}

父进程sleep5秒然后退出,子进程一直打印,通过监控脚本查看父子进程状态信息。
在这里插入图片描述
在这里插入图片描述
如果一个进程还在运行,而父进程退出了,此时该进程就被称为孤儿进程,被1号进程领养。1号进程被称为systemd,也就是操作系统。
在这里插入图片描述

进程优先级

优先级是指进程得到某种资源的先后顺序。
在这里插入图片描述
PRI即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高。
NI就是nice值,表示进程可被执行的优先级的修正数值。nice其取值范围是-20至19,一共40个级别。
加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
PRI(old)永远是80。
Linux进程优先级由pri和nice值共同确定。在linux中优先级的数值越小,优先级越高,优先级的数值越大,优先级越低。
用top命令更改已存在进程的nice:
1.top
2.进入top后按“r”–>输入进程PID–>输入nice值
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux进程 的相关文章

随机推荐

  • Spring 的基本用法之另外一种装配方式

    一 目的 了解 Spring 环境配置 掌握定义应用程序类 掌握编辑配置文件创建 bean 实例实现依赖注入 掌握编辑测试类创建 IoC 容器 通过容器获取 bean 实例 二 内容 创建一个Spring项目 完成主题为 订单信息通知 项目
  • 一些比较不错的资源网站

    阮一峰日志地址 Github上值得推荐的开源电子书
  • QT 5.15 源码windows下 msvc编译

    目录 1 下载 Qt 源代码 2 安装依赖项 3 配置命令行环境变量 4 构建 5 使用 1 下载 Qt 源代码 Index of archive qt 5 15 5 15 8 singlehttps download qt io arch
  • STM32F4XX/APM32F4XX USB OTA升级

    近期在研究USB CDC协议 使用USB Virtual Port Com功能与上位机通讯做了OTA功能 开发平台 MDK529开发硬件 APM32F411首先介绍一下程序执行逻辑 程序由两部分组成 Boot APP Flash由三部分组成
  • 485串口服务器协议,10/100M TCP/IP转1口RS-232/485/422串口服务器 - 宇泰(UTEK) - 全球领先智能通讯解决方案提供商!...

    gt gt 硬件特性 菜单配置界面 操作模式丰富 满足不同行业的应用 提供Windows 虚拟COM 驱动软件 灵活合理的UNIX 下Fixedtty 工作机制 具有1个串行端口 可以连接终端 Modem 条码机 收款机 ISDN 终端适配
  • 《网页设计基础——CSS的四种引入方式详解》

    网页设计基础 CSS的四种引入方式详解 一 行内式 规则 1 行内式是所有样式方法中最为直接的一种 它直接对HTML的标记使用style属性 然后将CSS代码直接写在其中 格式 p style color FF0000 font size
  • 用「渣男」心态去面试,爽翻!

    转载自博学谷公众号 面试是一场 销售 自己的考试 很多程序员掌握的技术 知识都非常过关 但在面试中却不能完全展现出来 屡屡发挥失常 同样是天选打工人 别人的offer 像猴子摘苞谷 应接不暇 而你的offer 像肉包子打狗 有去无回 究其根
  • python的环境变量配置

    一般会自己在安装时配置环境变量 但是也有小失误忘了打勾勾 这时我们则需要自己配置环境变量 Python的环境变量配置很简单 1 1 Windows配置环境变量 右击点击 我的电脑 点击 属性 2在弹出的界面中点击 高级系统设置 不同的win
  • 《MySQL实战45讲》——学习笔记33 MySQL Server查询结果的发送流程 / 一次查询大量数据对innoDB bufferPool的影响 / 内存淘汰算法LRU与innoDB改进的LRU

    本篇通过 大查询会不会把内存用光 这个问题 介绍了MySQL 的查询结果发送给客户端的过程 涉及的知识点包括 MySQL Server查询结果的发送流程 边读边发 MySQL线程状态Sending to client Sending dat
  • 面试题:软件测试工程师工作职责?

    软件测试工程师工作职责 工作职责 测试人员有不同的级别 或者说有不同的职位称呼 都有相对应不同的工作职责 如果你想了解现在企业里面最新的职位需求的话 最简单的一个方式就是直接去大型招聘网站上BOSS直聘或者前程无忧 赶集网去搜索软件测试工程
  • 前端表单验证 for循环验证 自定义表单验证

  • 关于Java的那些安全框架

    前言 在Java开发中 安全是一项至关重要的特性 不仅仅是因为它保护我们的数据和系统免受恶意攻击 还因为它保护着我们和我们的用户的隐私 因此 Java安全框架的选择至关重要 在本篇博客中 我们将探讨一些常见的Java安全框架 以及如何使用它
  • 微服务发展趋势

    目录 云原生网关逐步成型 服务网格回归理性 微服务架构分层逐渐清晰 微服务技术标准逐步形成 数据面 SidecarProxy 与 Proxyless 模式的融合 服务治理数据面透明化 控制面标准化 分布式事务从多样化到标准化 多语言解决方案
  • Android混合开发全解析

    现在的app都开始流行混合开发了 这是一个app开发的新技术 作为android程序猿的我们也应该要了解并且掌握他 那么在使用之前 我们一定要搞清楚 我们的哪些场景使用混合开发好一些呢 这个问题一定要搞清楚 因为现在的混合开发还不成熟 We
  • 测开基础知识02

    1 软件测试 软件测试 软件测试是软件研发的一部分 不止是找出软件错误的活动 是软件开发每一环节中一些列质量活动的总称 包括软件研发过程的改进 软件质量评定 需要参与到每一环关键的决策 发现程序中的错误 根据需求 分析执行软件的全过程 保证
  • lol英雄全皮肤爬取

    如何实现英雄联盟全皮肤 作为英雄联盟资深老玩家 想必大家都希望自己能拥有一套全皮肤 那么今天 小编就带着大家用网络爬虫的方式 爬取一套属于自己的全皮肤 冲 第一步 首先 打开我们全皮肤所在的网站 https 101 qq com hero
  • c#和c++的opencv位图数据参数互换问题解决方法

    1 C 调用vc dll 传递参数的问题 Bitmap 转换为 opencv mat 保存后图片不一样 vc 代码 bool Recognize Point 2F arr uchar b Mat src cv Mat 415 770 CV
  • 网络基础:网络协议及数据报格式

    网络应用程序设计模式 网络分层模型 两台计算机通过TCP IP协议通讯过程 协议格式 以太网帧格式 ARP探测的概念及数据报格式 ip段格式 UDP数据报格式 TCP数据报格式 TCP IP数据包封装 NAT映射与打洞机制 概念说明
  • 6950有史以来最经典玩机宝典/软件包/导航

    http www diypda com forum php mod viewthread tid 116274 教程 6950有史以来最经典玩机宝典 软件包 导航 复制链接 新支点6950玩机宝典 作为论坛资深认证商家和6950的改卡开发商
  • Linux进程

    目录 进程基本概念 描述进程PCB task struct内容分类 通过系统调用创建进程 fork 进程状态 Z zombie 僵尸进程 孤儿进程 进程优先级 进程基本概念 书上的概念是 进程是程序的一个执行实例 正在执行的程序等 在内核的