Linux 进程概念与进程状态

目录

  • 1. 冯诺依曼体系结构
  • 2. 操作系统(Operator System)
    • 2.1 概念
    • 2.2 设计OS的目的
    • 2.3 系统调用和库函数概念
  • 3. 进程概念
    • 3.1 描述进程 - PCB
    • 3.2 task_struct
    • 3.3 查看进程
    • 3.4 通过系统调用获取进程标识符PID, PPID
    • 3.5 通过系统调用创建fork
  • 4. 进程状态
    • 4.1 Linux内核代码描述的进程
    • 4.2 进程状态的查看
    • 4.3 Z(zombie) 僵尸进程
    • 4.4 孤儿进程

1. 冯诺依曼体系结构

我们常见的计算机, 比如笔记本, 不常见的计算机, 比如服务器, 大部分都遵守冯诺依曼体系结构。

在这里插入图片描述
截至目前,我们所认识的计算机, 都是由一个个的硬件组件组成。

  • 输入单元:包括键盘, 鼠标, 扫描仪, 写板等。
  • 中央处理器(CPU):含有运算器和控制器等。
  • 输出单元: 显示器, 打印机等。

注意:

  1. 这里的存储器指的是内存
  2. 不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输出或输入设备)
  3. 外设(输入或输出设备)要输入或者输出数据,也只能写入内存或者从内存中读取。
  4. 一句话,所有设备都只能和内存打交道

任何程序,运行的时候, 都必须从磁盘加载到内存,why?
答案:体系结构决定的。
为什么要有内存?
在这里插入图片描述
在这里插入图片描述

如果输入输出设备直接和CPU进行打交道, 那么效率太低了, 这样只能以外设的效率为主。
内存是CPU和外设之间的一个巨大缓存。

2. 操作系统(Operator System)

2.1 概念

任何计算机系统都包含⼀个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:

  • 内核(进程管理,内存管理,⽂件管理,驱动管理)
  • 其他程序(例如函数库,shell程序等等)

在这里插入图片描述

2.2 设计OS的目的

对下,与硬件交互,管理所有的软硬件资源(手段)
对上,为⽤⼾程序(应⽤程序)提供⼀个良好的执⾏环境(目的)

在这里插入图片描述

问题: 你的程序能直接写入硬件吗?
答案:不能, 都必须通过OS。

在这里插入图片描述
首先先看下面半部分, 那么操作系统是如何管理内存, 进程, 文件, 驱动的呢?

先描述,在组织。

把一个一个的硬件都描述成一个一个的链表, 然后链接起来,那么操作系统对于硬件的管理就相当于对链表的增删查改。
在这里插入图片描述
再看上面这部分, 操作系统不相信任何用户, 所以封闭起来,而 操作系统必须向上层提供各种接口,方便上层使用,也就是system call, 系统调用接口, 而系统掉哟接口,需要对操作系统有所了解, 使用起来会比较麻烦, 所以封装了各种的库, 方便我们进行系统的调用, 而这个接口只能是C语言接口, 因为这些系统调用都是C语言写的,所以所有的软件底层,都必须和C直接或者间接相关!

总结

计算机管理硬件

  1. 描述起来,⽤struct结构体
  2. 组织起来,⽤链表或其他⾼效的数据结构

2.3 系统调用和库函数概念

在开发⻆度,操作系统对外会表现为⼀个整体,但是会暴露⾃⼰的部分接⼝,供上层开发使⽤,这部分由操作系统提供的接⼝,叫做系统调⽤。

系统调⽤在使⽤上,功能⽐较基础,对⽤⼾的要求相对也⽐较⾼,所以,有⼼的开发者可以对部分系统调⽤进⾏适度封装,从⽽形成库,有了库,就很有利于更上层⽤⼾或者开发者进⾏⼆次开发。

那在还没有学习进程之前,就问⼤家,操作系统是怎么管理进⾏进程管理的呢?很简单,先把进程描述起来,再把进程组织起来!

3. 进程概念

课本概念:程序的⼀个执⾏实例,正在执⾏的程序等

内核观点:担当分配系统资源(CPU时间,内存)的实体。

这里进程可以认为
进程 = 内核数据结构(task_struct) + 程序的代码和数据

3.1 描述进程 - PCB

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

  • task_struct-PCB
    在Linux中描述进程的结构体叫做task_struct。
    task_struct是Linux内核的⼀种数据结构,它会被装载到RAM(内存)⾥并且包含着进程的信息。

3.2 task_struct

内容:

  1. 标⽰符: 描述本进程的唯⼀标⽰符,⽤来区别其他进程。
  2. 状态: 任务状态,退出代码,退出信号等。
  3. 优先级: 相对于其他进程的优先级。
  4. 程序计数器: 程序中即将被执⾏的下⼀条指令的地址。
  5. 内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
  6. 上下⽂数据: 进程执⾏时处理器的寄存器中的数据。
  7. I∕O状态信息: 包括显⽰的I/O请求,分配给进程的I∕O设备和被进程使⽤的⽂件列表。
  8. 记账信息: 可能包括处理器时间总和,使⽤的时钟数总和,时间限制,记账号等。
  9. 其他信息

组织进程

可以在内核源代码⾥找到它。所有运⾏在系统⾥的进程都以task_struct链表的形式存在内核⾥。

在这里插入图片描述

3.3 查看进程

  1. 进程的信息可以通过 /proc 系统⽂件夹查看
    在这里插入图片描述
  2. ⼤多数进程信息同样可以使⽤top和ps这些⽤⼾级⼯具来获取

在这里插入图片描述

3.4 通过系统调用获取进程标识符PID, PPID

进程id(PID)
⽗进程id(PPID)

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

3.5 通过系统调用创建fork

  1. 运⾏ man fork 认识fork
  2. fork有两个返回值
  3. ⽗⼦进程代码共享,数据各⾃开辟空间,私有⼀份(采⽤写时拷⻉)
  4. fork 之后通常要⽤ if 进⾏分流
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
 int ret = fork();
 if(ret < 0){
 perror("fork");
 return 1;
 }
 else if(ret == 0){ //child
 printf("I am child : %d!, ret: %d\n", getpid(), ret);
 }else{ //father
 printf("I am father : %d!, ret: %d\n", getpid(), ret);
 }
 sleep(1);
 return 0;
}
  1. id的返回值, 给父进程的是subpid,给子进程的返回值是0
  2. 一个变量怎么会有俩个返回值呢?为什么?
    因为需要进行独立, 怎么做到的TODO,fork之后,谁先运行,由操作系统的调度器自主决定。

4. 进程状态

首先来看一下进程的状态, 当然这是广义上操作系统的进程状态,并不是linux的进程状态

在这里插入图片描述

补充知识:

  1. 并行和并发

CPU执行进程代码,不是把进程执行完毕, 才开始进行下一个进程,而是给每一个进程分配一个时间片,基于时间片,进行调度轮转(单CPU下),此叫做并发。
解释一下:多个进程在一个CPU下采用进程切换的方式,在一段时间内,让多个进程都得以推进,称之为并发

并行:多个进程在多个CPU下分别,同时进行,这称之为并行。

  1. 时间片

Linux/Windows民用级别的OS,分时操作系统

  1. 等待的本质

链入目标外部设备,CPU不调度

在这里插入图片描述

只要进程在运行队列中,该进程就叫做运行状态。

运行和阻塞的本质:是让不同的进程,处在不同的队列中。
在这里插入图片描述

挂起(了解一下)

挂起分为运行时挂起和阻塞时挂起, 当内存资源严重不足时, 会利用swap分区(磁盘),将这些进程移至磁盘中, 用时间换空间。而服务器一般会禁用掉此功能, 因为挂起状态会频繁访问外设,效率太低。

4.1 Linux内核代码描述的进程

为了弄明⽩正在运⾏的进程是什么意思,我们需要知道进程的不同状态。⼀个进程可以有⼏个状态(在Linux内核⾥,进程有时候也叫做任务)

下⾯的状态在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 */
};

R运⾏状态(running): 并不意味着进程⼀定在运⾏中,它表明进程要么是在运⾏中要么在运⾏队列⾥。

S睡眠状态(sleeping): 意味着进程在等待事件完成(这⾥的睡眠有时候也叫做可中断睡眠(interruptiblesleep))。

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

T停⽌状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停⽌(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运⾏。

X死亡状态(dead):这个状态只是⼀个返回状态,你不会在任务列表⾥看到这个状态。

4.2 进程状态的查看

ps aux / ps axj 命令

a:显⽰⼀个终端所有的进程,包括其他⽤⼾的进程。

x:显⽰没有控制终端的进程,例如后台运⾏的守护进程。

j:显⽰进程归属的进程组ID、会话ID、⽗进程ID,以及与作业控制相关的信息

u:以⽤⼾为中⼼的格式显⽰进程信息,提供进程的详细信息,如⽤⼾、CPU和内存使⽤情况等

在这里插入图片描述

4.3 Z(zombie) 僵尸进程

僵死状态(Zombies)是⼀个⽐较特殊的状态。当进程退出并且⽗进程(使⽤wait()系统调⽤,后⾯讲)没有读取到⼦进程退出的返回代码时就会产⽣僵死(⼫)进程.

僵死进程会以终⽌状态保持在进程表中,并且会⼀直在等待⽗进程读取退出状态代码。

所以,只要⼦进程退出,⽗进程还在运⾏,但⽗进程没有读取⼦进程状态,⼦进程进⼊Z状态。

僵⼫进程危害:

进程的退出状态必须被维持下去,因为他要告诉关⼼它的进程(⽗进程),你交给我的任务,我办的怎么样了。可⽗进程如果⼀直不读取,那⼦进程就⼀直处于Z状态?是的!

维护退出状态本⾝就是要⽤数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态⼀直不退出,PCB⼀直都要维护?是的!

那⼀个⽗进程创建了很多⼦进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本⾝就要占⽤内存,想想C中定义⼀个结构体变量(对象),是要在内存的某个位置进⾏开辟空间!

内存泄漏?是的!

例子:

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

编译并在另⼀个终端下启动监控

在这里插入图片描述
开始测试

在这里插入图片描述

看到结果

在这里插入图片描述

4.4 孤儿进程

⽗进程如果提前退出,那么⼦进程后退出,进⼊Z之后,那该如何处理呢?

⽗进程先退出,⼦进程就称之为“孤⼉进程”

孤⼉进程被1号init进程领养,当然要有init进程回收喽。

例子:

#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){//child
 printf("I am child, pid : %d\n", getpid());
 sleep(10);
 }else{//parent
 printf("I am parent, pid: %d\n", getpid());
 sleep(3);
 exit(0);
 }
 return 0;
}

在这里插入图片描述


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

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

相关文章

计算机网络(14)ip地址超详解

先看图&#xff1a; 注意看第三列蓝色标注的点不会改变&#xff0c;A类地址第一个比特只会是0&#xff0c;B类是10&#xff0c;C类是110&#xff0c;D类是1110&#xff0c;E类是1111. IPv4地址根据其用途和网络规模的不同&#xff0c;分为五个主要类别&#xff08;A、B、C、D、…

shell脚本启动springboot项目

nohup java -jar springboot.jar > springboot.log 2>&1 & 表示日志输出重定向到springboot.log日志文件, 而原本的日志继续输出到 项目同级的log文件夹下, 所以这个重定向没必要. 我们没必要要2分日志 #!/bin/bash# 获取springboot项目的进程ID PID$(ps -e…

51c大模型~合集76

我自己的原文哦~ https://blog.51cto.com/whaosoft/12617524 #诺奖得主哈萨比斯新作登Nature&#xff0c;AlphaQubit解码出更可靠量子计算机 谷歌「Alpha」家族又壮大了&#xff0c;这次瞄准了量子计算领域。 今天凌晨&#xff0c;新晋诺贝尔化学奖得主、DeepMind 创始人哈萨…

FileProvider高版本使用,跨进程传输文件

高版本的android对文件权限的管控抓的很严格,理论上两个应用之间的文件传递现在都应该是用FileProvider去实现,这篇博客来一起了解下它的实现原理。 首先我们要明确一点,FileProvider就是一个ContentProvider,所以需要在AndroidManifest.xml里面对它进行声明: <provideran…

【Java】二叉树:数据海洋中灯塔式结构探秘(上)

个人主页 &#x1f339;&#xff1a;喜欢做梦 二叉树中有一个树&#xff0c;我们可以猜到他和树有关&#xff0c;那我们先了解一下什么是树&#xff0c;在来了解一下二叉树 一&#x1f35d;、树型结构 1&#x1f368;.什么是树型结构&#xff1f; 树是一种非线性的数据结构&…

网口输出的加速度传感器

一、功能概述 1.1 设备简介 本模块为了对电机、风机、水泵等旋转设备进行预测性运维而开发&#xff0c;只需一个模块&#xff0c; 就可以采集旋转设备的 3 路振动信号&#xff08;XYZ 轴&#xff09;和一路温度信号&#xff0c;防护等级 IP67 &#xff0c;能够 适应恶劣的工业…

力扣面试经典 150(上)

文章目录 数组/字符串1. 合并两个有序数组2. 移除元素3. 删除有序数组中的重复项4. 删除有序数组的重复项II5. 多数元素6. 轮转数组7. 买卖股票的最佳时机8. 买卖股票的最佳时机II9. 跳跃游戏10. 跳跃游戏II11. H 指数12. O(1)时间插入、删除和获取随机元素13. 除自身以外数组的…

浅谈 proxy

应用场景 Vue2采用的defineProperty去实现数据绑定&#xff0c;Vue3则改为Proxy&#xff0c;遇到了什么问题&#xff1f; - 在Vue2中不能检测数组和对象的变化 1. 无法检测 对象property 的添加或移除 var vm new Vue({data:{a:1} })// vm.a 是响应式的vm.b 2 // vm.b 是…

P4-1【应用数组进行程序设计】第一节——知识要点:一维数组

视频&#xff1a; P4-1【应用数组进行程序设计】第一节——知识要点&#xff1a;一维数组 项目四 应用数组进行程序设计 任务一&#xff1a;冒泡排序 知识要点&#xff1a;一维数组 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 用冒泡法对任意输入…

【数据库入门】关系型数据库入门及SQL语句的编写

1.数据库的类型&#xff1a; 数据库分为网状数据库&#xff0c;层次数据库&#xff0c;关系型数据库和非关系型数据库四种。 目前市场上比较主流的是&#xff1a;关系型数据库和非关系型数据库。 关系型数据库使用结构化查询语句&#xff08;SQL&#xff09;对关系型数据库进行…

day07(单片机高级)继电器模块绘制

目录 继电器模块绘制 原理图 布局 添加板框 布线 按tab修改线宽度 布线换层 泪滴 铺铜 铺铜的作用 铺铜的使用规范 添加丝印 步骤总结 继电器模块绘制 到淘宝找一个继电器模块 继电器模块的使用&#xff08;超详细&#xff09;_继电器模块工作原理-CSDN博客文章浏览阅读4.8w次&…

1+X应急响应(网络)病毒与木马的处置:

病毒与木马的处置&#xff1a; 病毒与木马的简介&#xff1a; 病毒和木马的排查与恢复&#xff1a;

【电路笔记 TMS320F28335DSP】时钟+看门狗+相关寄存器(功能模块使能、时钟频率配置、看门狗配置)

时钟源和主时钟&#xff08;SYSCLKOUT&#xff09; 外部晶振&#xff1a;通常使用外部晶振&#xff08;如 20 MHz&#xff09;作为主要时钟源。内部振荡器&#xff1a;还可以选择内部振荡器&#xff08;INTOSC1 和 INTOSC2&#xff09;&#xff0c;适合无需高精度外部时钟的应…

CCE-基础

背景&#xff1a; 虚拟化产生解决物理机资源浪费问题&#xff0c;云计算出现实现虚拟化资源调度和管理&#xff0c;容器出现继续压榨虚拟化技术产生的资源浪费&#xff0c;用命名空间隔离&#xff08;namespace&#xff09; 灰度升级&#xff08;升级中不影响业务&#xff09…

基于LLama_factory的Qwen2.5大模型的微调笔记

Qwen2.5大模型微调记录 LLama-facrotyQwen2.5 模型下载。huggingface 下载方式Modelscope 下载方式 数据集准备模型微调模型训练模型验证及推理模型导出 部署推理vllm 推理Sglang 推理 LLama-facroty 根据git上步骤安装即可&#xff0c;要求的软硬件都装上。 llama-factory运行…

提取图片高频信息

提取图片高频信息 示例-输入&#xff1a; 示例-输出&#xff1a; 代码实现&#xff1a; import cv2 import numpy as npdef edge_calc(image):src cv2.GaussianBlur(image, (3, 3), 0)ddepth cv2.CV_16Sgray cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)grad_x cv2.Scharr(g…

移动充储机器人“小奥”的多场景应用(上)

一、高速公路服务区应用 在高速公路服务区&#xff0c;新能源汽车的充电需求得到“小奥”机器人的及时响应。该机器人配备有储能电池和自动驾驶技术&#xff0c;能够迅速定位至指定充电点&#xff0c;为待充电的新能源汽车提供服务。得益于“小奥”的机动性&#xff0c;其服务…

怎么只提取视频中的声音?从视频中提取纯音频技巧

在数字媒体的广泛应用中&#xff0c;提取视频中的声音已成为一项常见且重要的操作。无论是为了学习、娱乐、创作还是法律用途&#xff0c;提取声音都能为我们带来诸多便利。怎么只提取视频中的声音&#xff1f;本文将详细介绍提取声音的原因、工具、方法以及注意事项。 一、为什…

Windows环境GeoServer打包Docker极速入门

目录 1.前言2.安装Docker3.准备Dockerfile4.拉取linux环境5.打包镜像6.数据挂载6.测试数据挂载7.总结 1.前言 在 Windows 环境下将 GeoServer 打包为 Docker&#xff0c;可以实现跨平台一致性、简化环境配置、快速部署与恢复&#xff0c;同时便于扩展集成和版本管理&#xff0c…

《Vue零基础入门教程》第四课: 应用实例

往期内容 《Vue零基础入门教程》第一课&#xff1a;Vue简介 《Vue零基础入门教程》第二课&#xff1a;搭建开发环境 《Vue零基础入门教程》第三课&#xff1a;起步案例 参考官方文档 https://cn.vuejs.org/api/application#create-app 示例 const {createApp} Vue// 通…