【Linux 08】进程概念

文章目录

  • 🌈 01. 基本概念
  • 🌈 02. 描述进程 PCB
  • 🌈 03. 使用 ./ 的方式创建进程
  • 🌈 04. ps 查看进程
  • 🌈 05. getpid / getppid 获取进程标识符
  • 🌈 06. kill 终止指定进程
  • 🌈 07. fork 创建子进程
  • 🌈 08. 进程状态
    • 1. 进程基本状态
    • 2. 查看进程状态
  • 🌈 09. 僵尸进程
  • 🌈 10. 孤儿进程

🌈 01. 基本概念

1. 课本概念

  • 程序的一个执行实例,表示正在执行的程序。
  • 一个任务就是一个进程,一个程序可以启动多个进程,程序只有一个,而一个程序可以有多个进程。

在这里插入图片描述

2. 内核概念

  • 分配系统资源 (CPU时间、内存) 的实体称为进程。

🌈 02. 描述进程 PCB

  • 将外存中的可执行程序的代码和数据加载到内存当中,但光凭对应的代码和数据不足以描述进程信息。
  • 进程信息被放在一个叫做==进程控制块 PCB (process control block) ==的结构体中。
  • 在操作系统学科中,每个进程都要有一个 struct PCB 的结构体来管理这些进程的信息,Linux 操作系统下的 PCB 就是 task_struct

在这里插入图片描述

  • 操作系统为了管理所有的进程,规定了一个进程,一定要有一个 PCB

进程的定义

  • 进程 = PCB + 自己的代码和数据
  • 对进程的管理就是对 PCB 构成的链表的增删查改操作。

🌈 03. 使用 ./ 的方式创建进程

  • ./某个可执行程序:本质就是让系统创建进程并运行。我们自己编写形成的可执行程序 = 系统命令 = 可执行文件。在 Linux 中运行的大部分执行操作,本质都是运行进程。

在这里插入图片描述

🌈 04. ps 查看进程

指令ps axj

功能:查看当前系统中所有正在运行的进程。

示例

  • 直接使用 ps axj 查看的是所有的进程信息

在这里插入图片描述

  • 如果需要查看指定进程则需要搭配 管道 | 和 grep 获取关键字信息这两个指令。

在这里插入图片描述

🌈 05. getpid / getppid 获取进程标识符

1. 进程标识符

  • pid:进程的 id,也成为进程的标识符,是每个进程所拥有的唯一标识符。
  • ppid:本进程的父进程的 id。

2. 获取进程 pid

  • getpid():获取进程自身的 pid。
  • getppid():获取进程的父进程的 pid。

3. 获取 pid / ppid 示例

  • 使用如下代码获取进程的 pid 并保证进程不会结束。
#include <unistd.h>
#include <iostream>
#include <sys/types.h>using std::cout;
using std::endl;int main()
{while(1){// 获取当前进程的 pid 与 ppidcout << "I am a process pid: " << getpid() << "ppid: " << getppid() << endl;sleep(1);}return 0;}
  • 发现获取到的进程 pid 和 ppid 与使用 ps 指令查询到的进程 pid 一致。

在这里插入图片描述
在这里插入图片描述

🌈 06. kill 终止指定进程

常见指令

指令功能
kill -9 pid终止指定 pid 所标识的进程
kill -19 pid暂定指定 pid 所标识的进程
kill -18 pid解除暂停 pid 所标识的进程

终止进程示例

  • 使用 getpid 获取到的 myprocess 进程的 pid 的来终止该进程。

在这里插入图片描述

🌈 07. fork 创建子进程

1. fork 的返回值说明

fork() 的返回值说明
返回值 < 0子进程创建失败
返回值 == 0子进程创建成功,返回子进程 pid 给父进程,返回 0 给子进程
子进程 pid表示父进程,父进程通过接收子进程 pid 管理子进程

2. 创建进程的本质

  • 创建一个进程,本质是系统中多出一个子进程,即多了一个内核 task_struct2,子进程与父进程都各自拥有自己的代码和数据。
  • 默认情况下,子进程会继承父进程的代码和数据,包括 PCB 也会以父进程的 PCB 为模板来初始化。
  • 父子进程之间代码共享,数据各自开辟空间,私有一份(采用写时拷贝)
  • 因为父子进程之间的代码是共享的,在执行子进程自己的代码时会顺带着再执行一遍父进程的代码,这种情况下,创建出子进程就没有任何意义了。
  • 因此在 fork 之后,如果想要单独执行子进程的数据,就要使用 if 对父子进程的代码和数据进行分流

3. 创建子进程的原因

  • 希望子进程和父进程执行不一样的代码部分,让多个进程并发跑起来。

4. 多进程中使用 if 让父子进程执行不同的代码

#include <unistd.h>
#include <iostream>
#include <sys/types.h>using std::cout;
using std::endl;int main()
{                                                                                                                                                                             pid_t id = fork();if (0 == id)    // 执行子进程部分代码  cout << "I am child process" << endl;  else if(id < 0) // 子进程的创建失败了cout << "process creation failure" << endl;else            // 执行父进程部分代码                                                                                                                            cout << "I am parent process" << endl;return 0;                               
}
  • 父子进程各执行了自己的那部分代码。
  • 关于 fork 函数为什么会有两个返回值的问题看虚拟地址空间 + 父子写时拷贝

在这里插入图片描述

🌈 08. 进程状态

1. 进程基本状态

  • 任何一个进程在运行的时候都要有对应的状态,一个进程可以拥有几个状态。
  • 进程状态是 task_struct 内部的一个属性,更改进程状态就是更改其状态属性。
状态标识符标识符说明状态说明
R运行状态 running进程处于运行中或运行队列里
S睡眠状态 sleeping浅度睡眠,进程在等待 “资源” 就绪,睡眠状态可被中断
D磁盘休眠状态 disk sleep深度睡眠,不可中断睡眠,该状态的进程不会被操作系统干掉
T停止状态 stoppedkill -19 pid 暂停进程;kill -18 pid 解除暂停
Z僵尸状态 zombies进程退出时,会暂时处于僵尸状态,要将退出信息保留在自己的 PCB 中,没人读取这些退出信息回收该进程时,该进程就不会释放,此时就一直处于僵尸状态

2. 查看进程状态

1. R 运行状态

  • 编写一段死循环的代码,能够让 CPU 一直处在运行状态。
#include <iostream>
#include <unistd.h>
#include <sys/types.h>int main()                                                                         
{while(1);return 0;
}
  • R+ 表示该进程在前台运行

在这里插入图片描述

2. S 睡眠状态

  • 编写如下一段死循环打印的代码。
#include <iostream>
#include <unistd.h>
#include <sys/types.h>int main()                                                                         
{while(1)cout << "sleeping" << endl;return 0;
}
  • 因为 CPU 绝大部分时间都 在等待显示器打印信息,因此绝大部分时间处于睡眠状态。

在这里插入图片描述

3. T 暂停状态

  1. 暂停指定进程:kill -19 对应进程 pid

在这里插入图片描述

  1. 解除进程暂停:kill -18 对应进程 pid,恢复的进程会跑到后台状态自动变成 R。

在这里插入图片描述

🌈 09. 僵尸进程

僵尸进程概念

  • 已经运行完毕,但是需要维持自己的退出信息,自己的进程 task_struct 会记录自己的退出信息,未来让父进程读取。
  • 子进程退出时不会立即退出,此时处于僵尸状态,父进程没有读取到退出信息,无法对该进程回收时就会一直处于僵尸状态。无法使用 kill 指令干掉僵尸进程。
  • 僵尸进程会以终止状态保持在进程表中,并且会一直等待父进程读取退出状态代码。
  • 如果一直处于僵尸状态,即僵尸进程一直存在,则会造成内存泄漏

僵尸进程示例

  • 使用如下代码让父进程多运行一会,保证子进程退出时,父进程还在运行。
#include <iostream>
#include <unistd.h>
#include <sys/types.h>using std::cout;
using std::endl;int main()
{pid_t id = fork();if (0 == id)	// 子进程{cout << "I am child pid: " << getpid() << endl;sleep(5);}else			// 父进程{cout << "I am father ppid: " << getppid() << endl;sleep(100);}return 0;
}     

在这里插入图片描述
在这里插入图片描述

🌈 10. 孤儿进程

孤儿进程概念

  • 孤儿进程听名字就知道是个什么东西,父进程如果先行退出,子进程就会变成孤儿进程。
  • 为了避免未来孤儿进程在退出后无法被回收,因此孤儿进程会被 1 号进程 (操作系统) 领养

孤儿进程示例

  • 对僵尸进程的示例代码进行改动,让父进程先行结束掉,即可看到孤儿进程的情况。
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>using std::cout;
using std::endl;int main()
{pid_t id = fork();if (0 == id)	// 子进程{cout << "I am child pid: " << getpid() << endl;sleep(100);}else			// 父进程{cout << "I am father ppid: " << getppid() << endl;sleep(5);exit(0);}return 0;
}
  • 通过图 1 可以看到子进程 28689 的父进程 ppid 是 26543,图 2 在执行完父进程后,子进程 28689 的父进程就变成了 1 号进程。

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

tftp使用

下载 sudo apt-get install tftpd-hpa 创建文件夹 mkdir /home/ljl/work/tftpd mkdir /home/ljl/tftpd chmod 777 tftpd/编辑 sudo vim /etc/default/tftpd-hpa //服务器端 sudo apt-get install tftp-hpa //客户端编辑权限 sudo vi /etc/default/tftpd-hpa 内容&#xff1…

1. 列表补全

while 1:try:offset,n,l1,l2 map(int,input().split())start1 end1 start2 end2 0if offset>l1: # 有被跳过的页start1 end1 l1if offset>l1l2: # 第二页是否被跳过start2 end2 l2else: # 第二页被展示的部分start2,end2 offset-l1…

SQL Server 2008R2 日志文件大小设置及查询

SQL Server 2008R2 建立数据库存在日志无限增长问题&#xff0c;造成磁盘内存不足。本文解决这个问题&#xff0c;如下&#xff1a; 1.设置日志文件的最大大小 USE master; GO ALTER DATABASE [D_total] MODIFY FILE (NAME D_total_log, -- 日志文件的逻辑名称MAXSIZE 200…

【黄啊码】如何用GPT和向量数据库做问答型AI

知识库服务依赖该数据库&#xff0c;Embedding 形式个性化训练 ChatGPT&#xff0c;必不可少的就是向量数据库 因为 qdrant 向量数据库只支持 Docker 部署&#xff0c;所以需要先安装好 Docker 服务。 命令行安装 拉取镜像 docker pull qdrant/qdrant 运行服务 docker run -…

飞桨AI应用@riscv OpenKylin

在riscv编译安装飞桨PaddlePaddle参见&#xff1a; 算能RISC-V通用云编译飞桨paddlepaddleopenKylin留档_在riscv下进行paddlelite源码编译-CSDN博客 安装好飞桨&#xff0c;就可以用飞桨进行推理了。刚开始计划用ONNX推理&#xff0c;但是在算能云没有装上&#xff0c;所以最…

【正点原子Linux连载】第十七章 异步通知实验 摘自【正点原子】ATK-DLRK3568嵌入式Linux驱动开发指南

1&#xff09;实验平台&#xff1a;正点原子ATK-DLRK3568开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id731866264428 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/docs/boards/xiaoxitongban 第十七…

C 经典面试题15例

1.引用与指针有什么区别? 答 、1) 引用必须被初始化&#xff0c;指针不必。 2) 引用初始化以后不能被改变&#xff0c;指针可以改变所指的对象。 3) 不存在指向空值的引用&#xff0c;但是存在指向空值的指针。 2. 描述实时系统的基本特性 答 、在特定时间内完成特定的任…

2024年华为OD机试真题-石头剪刀布游戏-Python-OD统一考试(C卷)

题目描述: 石头剪刀布游戏有3种出拳形状:石头、剪刀、布。 分别用字母 A,B,C表示。 游戏规则: 1)出拳形状之间的胜负规则如下:A> B;B> C;C> A “>” 左边一个字母,表示相对优势形状。 右边一个字母,表示相对劣势形状。 2) 当本场次中有且仅有一种出拳形状…

Java发送请求-get源码

发送请求 配置依赖-pom.xml Welcome! - The Apache HTTP Server Project 官网解释这个源码httpClient是执行httpget和httppost 步骤&#xff1a; 查看httpClient源码&#xff0c;源码和方法都没有有用的解释 查看CloseableHttpClient源码类 这个抽象类实现2个接口&#xf…

使用conda创建python 虚拟环境

在cmd命令窗口&#xff0c;输入conda activate激活虚拟环境&#xff0c;可以看到默认为base&#xff0c;下面来介绍如何使用conda来创建python虚拟环境&#xff0c;因为在不同的工程中&#xff0c;对python等有不同版本需求&#xff0c;容易出现冲突。 1. 安装conda &#xff…

TCP与UDP:网络协议的技术原理与要点

文章目录 1. TCP&#xff08;传输控制协议&#xff09;1.1 面向连接1.1.1 三次握手1.1.2 四次挥手 1.2 可靠性1.3 有序传输1.4 流量控制1.5 拥塞控制 2. UDP&#xff08;用户数据报协议&#xff09;2.1 无连接2.2 不可靠性2.3 无序传输2.4 简单 3. TCP和UDP的头部结构4. TCP和U…

LeetCode232:用栈实现队列

题目描述 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int peek() 返…

docker 哲学 - 网络桥接器、容器网络接口 、容器间的通信方式

1、解释 docker0 veth eth 2、vethXX 和 ethXX 是肯定一一对应吗 比如 eth1 对应 veth1 3、如果 A容器使用 默认创建方式 。定义他内部网络为 eth0&#xff0c;容器B使用 --network 连上 已创建的网络 172.89.2.1 。此时假设 B的 ip是 172.89.2.2 &#xff0c;容器网络接口是 e…

2024年企业级通用人工智能的关键技术趋势

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

腾讯三面被问到有没有参加过CTF_我反手就是一套军体拳打得面试官哑口无言!

目录 ​ 前言&#xff1a; 正文&#xff1a; 什么是CTF&#xff1f; 什么是PWN? 为什么要学CTF&#xff1f; CTF竞赛模式&#xff1a; CTF各大题型简介&#xff1a; 学之前的思考&#xff1a;分析赛题情况 常规做法 CTF比赛需要的知识储备 CTF比赛的神器&#xff…

51单片机中断信号的种类及应用场景

在嵌入式系统中&#xff0c;中断是一种重要的事件处理机制&#xff0c;它可以在程序执行的任何时候暂停当前任务&#xff0c;转而执行与之相关的特殊任务或事件。51单片机作为一种常见的微控制器&#xff0c;其中断功能在各种应用中起着关键作用。然而&#xff0c;对于初学者和…

Jmeter-基础元件使用(二)-属性及对数据库简单操作

一、Jmeter属性 当我们想要在不同线程组中使用某变量&#xff0c;就需要使用属&#xff0c;此时Jmeter属性的设置需要函数来进行set和get操作 1.创建set函数 2.然后采用Beanshell取样器进行函数执行 3.调用全局变量pro_id 4.将上面生成的函数字符串粘贴到另一个线程组即可…

二、阅读器的开发(初始)-- 2、阅读器开发

1、epubjs核心工作原理 1.1 epubjs的核心工作原理解析 epub电子书&#xff0c;会通过epubjs去实例化一个Book对象&#xff0c;Book对象会对电子书进行解析。Book对象可以通过renderTo方法去生成一个Rendition对象&#xff0c;Rendition主要负责电子书的渲染&#xff0c;通过R…

PointNet++论文复现(一)【PontNet网络模型代码详解 - 分类部分】

PontNet网络模型代码详解 - 分类部分 专栏持续更新中!关注博主查看后续部分! 分类模型的训练: ## e.g., pointnet2_ssg without normal features python train_classification.py --model pointnet2_cls_ssg --log_dir pointnet2_cls_ssg python test_classification.py…

景区污水处理设备亮点及价格分析

诸城市鑫淼环保小编带大家了解一下景区污水处理设备亮点及价格分析 美丽景区的治理过程中&#xff0c;废水处理至关重要&#xff0c;为您提供一体化污水处理设备和溶气气浮机&#xff0c;致力于解决污水排放问题。我们的设备节能高效、占地小、运行稳定&#xff0c;助您轻松达标…