【Linux 08】进程概念

news2024/9/28 11:15:23

文章目录

  • 🌈 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 号进程。

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

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

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

相关文章

unity学习(67)——控制器Joystick Pack方向

1.轮盘直接复制一个拖到右边就ok了&#xff0c;轮盘上是有脚本的。&#xff08;只复制&#xff09; 2.上面的显示窗也可以复制&#xff0c;但是要绑定对应的轮盘&#xff08;unity中修改变量&#xff09;&#xff0c;显示窗上是有脚本的。&#xff08;复制改变量&#xff09; 3…

分享 | 使用Virtuoso VCPVSR工具基于标准单元的布局布线流程

​ 本节内容 导览 一、准备工作 二、运行VCP前的配置 三、VCP的布局规划 四、VCP的自动摆放 五、VSR的自动绕线 分享使用Virtuoso GXL Custom Digital Placer(VCP) & Space-based Router(VSR)工具进行基于纯数字Standard-Cell布局布线的操作流程。 VCP&VSR演…

解决mysql问题: this is incompatible with sql_mode=only_full_group_by

今天在部署一趟测试环境的服务&#xff0c;各种配置文件都配好了&#xff0c;启动服务后台报错&#xff0c;解决后记录一下&#xff0c;小伙伴们也可以看看&#xff01; ### Cause: java.sql.SQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause…

Mac nvm install failed python: not found

报错 $>./configure --prefix/Users/xxx/.nvm/versions/node/v12.22.12 < ./configure: line 3: exec: python: not found nvm: install v12.22.12 failed!解决方法 到 App 文件夹&#xff0c;并且打开 cd /System/Applications/Utilities/ open .记得改完 Rosetta 之…

Nginx 全局块配置 worker 进程的两个指令

1. 前言 熟悉 nginx 运行原理的都知道&#xff0c;nginx 服务启动后&#xff0c;会有一个 master 进程和多个 worker 进程&#xff0c;master 进程负责管理所有的 worker 进程&#xff0c;worker 进程负责处理和接收用户请求 在这里我们所要研究的是 master 进程一定要创建 wo…

java网络原理(三)----三次握手四次挥手

三次握手 三次握手是建立连接的过程&#xff0c;四次挥手是断开连接的过程&#xff0c;三次握手发生在socket.accept()之前。 客户端和服务器尝试建立连接的时候服务器就会和客户端进行一系列的数据交换称为握手&#xff0c;这个过程建立完了后&#xff0c;连接就好了。 A和B…

【蓝桥杯嵌入式】四、各种外设驱动(九)ADC(1):软件触发与中断触发方式

温馨提示&#xff1a;本文不会重复之前提到的内容&#xff0c;如需查看&#xff0c;请参考附录 【蓝桥杯嵌入式】附录 目录 重点提炼&#xff1a; 一、需求分析 1、需要的外设资源分析&#xff1a; 2、外设具体分析&#xff1a; 比赛时ADC可能需要配置的部分&#xff1a;…

第十三届蓝桥杯物联网试题(省赛)

做后感悟&#xff1a; OLED显示函数需要一直显示&#xff0c;所以在主函数中要一直循环&#xff0c;为了确保这个检错功能error只输出一次&#xff0c;最好用中断串口进行接收数据&#xff0c;数据收完后自动进入中断函数中&#xff0c;做一次数据检查就好了&#xff0c;该开灯…

十三、MySQL基于GTID的半同步复制

目录 一、MySQL半同步复制 一、三种复制方式比较 1、异步复制 2、同步复制 3、半同步复制 4、半同步复制比较 5、半同步复制的特点 二、搭建半同步复制 1、如果不清楚Plugin的目录&#xff0c;用如下查找&#xff1a; 2、所有数据库服务器&#xff0c;安装半同步插件…

如何使用ospf (enps) 简单实践ospf协议

1. OSPF的基本概念 OSPF&#xff08;Open Shortest Path First&#xff0c;开放式最短路径优先&#xff09;是一种广泛应用于TCP/IP网络中的内部网关协议&#xff08;Interior Gateway Protocol, IGP&#xff09;&#xff0c;主要用于在同一自治系统&#xff08;Autonomous Sys…

Django的forms组件

divmod(被除数, 除数)传入两个参数之后得到一个元组,元组中的第一个值是商,第二个是余数 forms组件 写一个注册功能,获取用户名和密码,利用form表单提交数据,在后端判断用户名和密码是否符合一定的条件:用户名必须超过3个字,密码最多6位.最后将验证信息返回到前端页面 1.手动…

【Algorithms 4】算法(第4版)学习笔记 21 - 5.2 单词查找树

文章目录 前言参考目录学习笔记0&#xff1a;前置介绍0&#xff1a;前置介绍1&#xff1a;单词查找树 R-way tries1.1&#xff1a;介绍1.2&#xff1a;查找操作1.2.1&#xff1a;成功命中1.2.2&#xff1a;未命中1.3&#xff1a;插入操作1.4&#xff1a;Java 实现1.5&#xff1…

刷题DAY31 | LeetCode 455-分发饼干 376-摆动序列 53-最大子序和

455 分发饼干&#xff08;easy&#xff09; 假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并…

惠普EliteBook使用VirtualBox安装ISO镜像

实验环境 虚拟机软件&#xff1a;Oracle VM VirtualBox 6.1.16镜像文件&#xff1a;CentOS-7-x86_64-Minimal-2009.iso笔记本&#xff1a;惠普EditBook操作系统&#xff1a;Window10 BIOS开启虚拟化技术 一遍笔记本都不会开启虚拟化技术的&#xff0c;但是在window里使用虚拟…

二叉树|257.二叉树的所有路径

力扣题目链接 class Solution { private:void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {path.push_back(cur->val); // 中&#xff0c;中为什么写在这里&#xff0c;因为最后一个节点也要加入到path中 // 这才到了叶子节…

Qt实现TFTP Server和 TFTP Client(一)

1 概述 TFTP协议是基于UDP的简单文件传输协议&#xff0c;协议双方为Client和Server.Client和Server之间通过5种消息来传输文件,消息前两个字节Code是消息类型&#xff0c;消息内容随消息类型不同而不同。传输模式有三种&#xff1a;octet,netascii和mail&#xff0c;octet为二…

nodejs安装使用React

1、react安装 首先&#xff0c;确保电脑上具备nodejs环境&#xff0c;之后用 winr 呼出控制台&#xff0c;输入 cmd 命令弹出cmd控制台&#xff08;小黑框&#xff09;之后在默认路径输入如下代码 npm i -g create-react-app //全局安装react环境无需选择特定文件夹安装成功后…

代码随想录--排序算法

912.排序数组 快速排序 思路&#xff1a; 1. 设置一个pivot2. 将小于nums[pivot]的值 放在左边3. 将 大于nums[pivot]的值 放在 右边4. 递归调用注意&#xff1a;必须先比较nums[high] 与pivot 代码&#xff1a; class Solution {int partition(vector<int>&nu…

论文解读:Frozen Feature Augmentation for Few-Shot Image Classification

文章总结 动机 通过各种图像增强手段和冻结特征(已经训练好的特征)结合起来训练轻量级模型。 最终得到的最佳设置顺序 亮度&#xff0c;对比度FroFA (C)和后置cFroFA (Pc) 这三种连续的数据增强操作(具体这三种数据增强操作是干了什么&#xff0c;得去附录找) 这里三种FroFA…

国内IP地址格式的多样性与规范化

在当今数字化时代&#xff0c;IP地址作为互联网通信的基本要素之一&#xff0c;在网络通信中扮演着至关重要的角色。了解国内IP地址的格式、规范以及不同类型的IP地址对网络通信的影响&#xff0c;对于构建高效稳定的网络环境至关重要。虎观代理小二将深入探讨国内IP地址的格式…