【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 与 ppid
     	cout << "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 号进程。

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

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

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

相关文章

设置asp.net core WebApi函数输入和返回类型中的属性名称开头大小写格式

以下列类型定义为例创建简单的ASP.NET Core的WebApi函数&#xff0c;此时输入参数和返回结果的属性名称开头默认为小写&#xff0c;如下图所示。 public class UserInfo { public string UserName { get; set; }public string UserSex { get; set; }public string UserP…

利用瑞士军刀netcat建立连接并实现文件上传

实验环境&#xff1a; Kali:192.168.117.129 Windows10:192.168.135.142 第一步&#xff1a;建立连接 在Windows上下载netcat(官网搜索) 下载好之后在netcat目录打开cmd进入小黑屏 实验一&#xff1a;建立虚拟机与主机的连接 命令&#xff1a; Kali:nc 192.168.135.144…

观成科技:白象组织BADNEWS木马加密通信分析总结报告

概述 白象&#xff0c;又名Hangover、Patchwork、摩诃草等&#xff0c;该组织主要针对中国、巴基斯坦等亚洲地区国家进行网络间谍活动&#xff0c;攻击目标以政府机构、科研教育领域为主。 自16年起&#xff0c;该APT组织一直持续使用攻击武器BADNEWS开展攻击活动&#xff0c…

C++:变量和常量(3)

变量 什么是变量&#xff1a;变量就是一个装东西的盒子 通俗&#xff1a;变量是用于存放数据的容器。我们通过变量名获取数据&#xff0c;甚至数据可以修改 变量的作用&#xff1a;给指定的内存空间起名&#xff0c;后期通过起的名字就可以调用整个内存空间 定义变量的格式 &a…

Jenkins--在Linux上使用Docker安装

一、Jenkins 简介 Jenkins是一个流行的开源自动化服务器&#xff0c;用于持续集成和持续交付&#xff08;CI/CD&#xff09;。Jenkins的核心功能主要包括以下几点&#xff1a; 持续集成&#xff1a;Jenkins可以监控版本控制系统&#xff08;如Git、SVN&#xff09;中的代码变…

pytorch+tensorboard

安装依赖 pip install teorboard pip install torch_tb_profiler了解teorboard 记录并可视化标量[组]、图片[组]。 如何使用 第一步:构建模型,记录中间值,写入summarywriter 每次写入一个标量add_scalar 比如: from torch.utils.tensorboard import SummaryWriter wr…

三、阅读器开发--4、阅读器目录、全文搜索功能开发

1、阅读器目录 1.1、实现目录 先实现目录的布局 定义一个蒙版&#xff0c;充满整个屏幕浮在阅读器上方&#xff0c;左侧为目录右侧为背景&#xff0c;目录下方包含一个tab&#xff0c;点击后会切换不同的内容&#xff0c;这里tab是目录、书签&#xff0c;这里可以通过如下的…

华为设备配置攻击防范

组网需求 如图1所示&#xff0c;如果局域网内存在Hacker向RouterA发起畸形报文攻击、分片报文攻击和泛洪攻击&#xff0c;将会造成RouterA瘫痪。为了预防这种情况&#xff0c;管理员希望通过在RouterA上部署各种攻击防范措施来为用户提供安全的网络环境&#xff0c;保障正常的…

【Canvas与艺术】模拟八一电影制片厂电影片头效果

【缘起】 八一厂每部电影前都有其专有开头&#xff0c;如&#xff1a;https://www.ixigua.com/6799821997258834440?logTag2eacce76401e13f9efe7 这个片头可以用canvas模拟下来。 【关键点】 线型放射状粒子系统的运作。 立体感五角星的绘制。 【图例】 【代码】 <!D…

springBoot+ureport报表引擎

UReport是一款基于单元格迭代模型的纯Java中式报表引擎。它架构于Spring之上&#xff0c;因此与企业应用具有良好的集成能力。UReport提供了基于Eclipse插件与基于网页的两种报表模版设计方式&#xff0c;采用类Excel报表模版设计风格&#xff0c;简单、易上手&#xff0c;可在…

Nginx配置静态代理/静态资源映射时root与alias的区别,带前缀映射用alias

场景 Nginx搭建静态资源映射实现远程访问服务器上的图片资源&#xff1a; Nginx搭建静态资源映射实现远程访问服务器上的图片资源_nginx 当作图片资源访问 博客-CSDN博客 以上在配置静态资源映射时使用的如下配置 location / {root D:/pic_old/;try_files $uri $uri/ /ind…

游戏开发笔记:游戏海外版本时区问题(解释时区问题,分解为js写法和lua写法来分析记录,整理出对应语言的相关函数方法。)

对于海外游戏而言,与时间相关的功能,都不能忽略时区的计算。根据 ‘ 服务端资源是有限的,客户端资源是无穷无尽的 ’的定义来说,基本上时区包括时间的计算都是由客户端来进行计算,今天内容也是围绕客户端来展开。 时区算法常见的时间描述时区需要计算的点在lua语言中的写…

//简单函数_素数距离问题

任务描述 现在给出你一些数&#xff0c;要求你写出一个程序&#xff0c;输出这些整数相邻最近的素数&#xff0c;并输出其相距长度。如果左右有等距离长度素数&#xff0c;则输出左侧的值及相应距离。 如果输入的整数本身就是素数&#xff0c;则输出该素数本身&#xff0c;距离…

谷歌Google广告推广开户和投放攻略?

随着出海市场增加&#xff0c;越来越多的中国企业选择借助谷歌Google广告这一全球最大的在线广告平台&#xff0c;拓展海外市场&#xff0c;提升品牌知名度和产品销量。在这个过程中&#xff0c;选择一家专业且富有实战经验的服务商至关重要&#xff0c;而云衔科技正是这样一位…

看奈飞三体魔改 赏国产《三体》预告片AI重制版

看奈飞三体魔改 赏国产《三体》预告片AI重制版 In the vast expanse of the universe, secrets await to be uncovered. 宇宙无垠&#xff0c;秘密待揭。 A signal from the depths of space leads to an encounter with an alien civilization - the Trisolarans. 深空信号引…

nvic优先级溢出

nvic的抢占优先级大于当前的配置群组所要求的最大上限&#xff0c;则真正优先级为数值的溢出部分&#xff1b;如果溢出部分为0则循环为最大数据&#xff1a; 如上图所示&#xff1a;中断分组为2&#xff1a; 因此优先级因为0--3 TICK_INT_PRIORITY等于0xf即为15&#xff1b;与3…

何时需要指定泛型:Scala编程指南

这里写目录标题 何时需要指定泛型&#xff1a;Scala编程指南为什么使用泛型类型安全 何时需要指定泛型结论 何时需要指定泛型&#xff1a;Scala编程指南 在Scala编程中&#xff0c;泛型是一种强大的特性&#xff0c;它允许开发者编写灵活且类型安全的代码。然而&#xff0c;正…

kubectl 启用shell自动补全功能

官网手册参考&#xff1a;https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-linux/ 系统&#xff1a;centos7 补全脚本依赖于工具 bash-completion&#xff0c; 所以要先安装它&#xff08;可以用命令 type _init_completion 检查 bash-completion 是否已安装&a…

聚合支付备案新增机构名单公布,14家机构成功备案

孟凡富 3月27日&#xff0c;中国支付清算协会公布了最新一批收单外包服务机构备案机构结果&#xff0c;总备案机构为27000家&#xff0c;新增备案机构为648家&#xff0c;其中&#xff0c;新增聚合支付技术服务备案机构包括北京鑫杰华誉、深圳中峻、多点(深圳)数字科技、扬州泽…

基于MATLAB的模糊神经网络预测水质评价

%% 学习目标&#xff1a;模糊神经网络预测水质评价 %% 更多matlab精彩专题课程和案例&#xff0c;可以搜索微信公众号&#xff1a;电击小子程高兴的MATLAB小屋 %% 清空环境变量 clc clear%% 参数初始化 xite0.001; alfa0.05;%% 网络节点 I6; %输入节点数 M12; %隐含节点数…