深入理解Linux进程管理机制

个人主页:chian-ocean

文章专栏-Linux

前言

进程 是现代操作系统中一个不可或缺的概念,其主要目的在于管理资源、实现并发、提高系统效率,并确保系统的稳定性和安全性。

进程的定义

进程(Process) 是计算机操作系统中的一个基本概念,指的是一个正在运行的程序的实例。它是程序在计算机中执行的动态表现,不仅包含程序的代码(即可执行指令),还包括程序在运行时所需的各种资源,如内存、文件句柄、CPU时间等。

  1. 在理解操作系统的时候,OS是一个进行软硬件管理的软件。
  2. 进程 通俗的理解就是一个被加载到内存的程序(进程也叫任务

OS如何管理进程

在理解操作系统的时候提出来 ,OS进行管理是 先描述后组织

  • 任何一个进程在被加载在内存的时候形成一个一个进程,这时候操作OS进行描述的过程。

PCB

PCB的理解

学校在对一个人管理学生的时候需要记录一个人的基本信息(是所有学生所共有的特征)有,姓名、身高、体重、身份证等等。OS引入了PCB(Process Ctrl Block)进程控制块:进程属性的集合(也就是描述的过程)

  • 进程控制块(Process Control Block, PCB)是操作系统中用于描述和控制一个进程的最重要的数据结构。
  • 可以把PCB理解为一个进程的"身份证",它包含了操作系统对每个进程管理和调度所需要的所有信息。
  • 当一个程序被创建并执行时,操作系统就为它创建一个PCB,用来追踪和管理它的状态。

PCB的内容

PCB的本质就是结构体(struct),里面储存了各种各样的信息,例如:

  • 进程标识信息:进程ID(PID),父进程ID(PPID),用于唯一标识进程和维护进程关系。
  • 进程状态:描述当前进程的状态,如就绪、运行、阻塞等。
  • CPU寄存器和程序计数器:保存当前的CPU状态,以便进行上下文切换。
  • 内存管理信息:如页表、段表,用于描述进程的内存空间。
  • 调度信息:包括进程优先级、时间片等,用于进程调度。
  • 资源信息:记录进程打开的文件描述符和使用的I/O设备。

通俗的讲:进程控制块(PCB,Process Control Block)本质上是一个数据结构,它是操作系统用来描述、管理和控制一个进程的所有关键信息的集合

形象的表述为

bash 复制代码
# 进程 = PCB(内核操作系统数据结构) + 自己数据代码

通过复杂的数据结构相互联系,形成有序的属性集合的连接(组织的过程

Linux系统下进程的管理

上述说OS是通过PCB进行进程的管理,在Linux下的PCB是tast_struct(tast_struct是PCB的一种),Linux下管理为2点

  1. Linux系统下通过task_struct进行属性的描述。
  2. Linux系统下本质是通过双链表进行连接,进而达到OS对进程的管理

查看正在跑的进程:

特别说明:

  • CWD(Current Working Directory) ,即当前工作目录
  • exe是你正在执行的文件

CWD的作用

  • 文件路径解析 :在操作文件时,如果给定的路径是相对路径,那么相对路径就是基于当前工作目录进行解析的。例如,如果当前工作目录是/home/user,而你输入命令cat example.txt,系统会寻找/home/user/example.txt这个文件。

查看标识符

bash 复制代码
# 输入:
ps ajx | head -1 ; ps ajx | grep 18549

看向第二行:

  • **PID(Process Identifier,进程标识符)**是操作系统分配给每个正在运行的进程的一个唯一标识符,用于区分不同的进程。

  • PPID(Parent Process Identifier) 是操作系统中用于标识一个进程的父进程 的标识符。每个进程都有一个PID(Process ID),此外也有一个PPID,它用来表示该进程是由哪个进程创建的。

bash 复制代码
# 我们过滤信息,为什么会出现这一行
17986 18592 18591 17986 pts/1    18591 S+    1000   0:00 grep --color=auto 18549

# 我们在过滤信息的通过`grep`, 这个也是个进程,所以在查看进程时过滤信息时候,grep也存在。

通过系统调用可以调用到获得PID和PPID

cpp 复制代码
  1 #include<iostream>
  2 #include <unistd.h>
  3 #include<sys/types.h>
  4 using namespace std;
  5 
  6 int main()
  7 {
  8     while(true)
  9     {
 10         cout << "进程id:"<< getpid() <<endl;  // 调用PID
 11         cout << "进程pid:"<< getppid() <<endl; // 调用PPID
 12         sleep(3);
 13     }
 14     return 0;
 15 }

执行结果:

bash 复制代码
ps ajx | head -1 ; ps ajx | grep 19038
  • bash的PID是process的PPID
  • bashprocess的父进程,二者构成父子进程

通过系统调用创建进程

fork()介绍

fork() 是操作系统中的一个关键系统调用,用于在运行的进程中创建一个新的进程。它最常用于Unix和Linux 操作系统中,通过调用fork(),一个现有的进程可以复制出一个新进程 。被创建的新进程被称为子进程(Child Process) ,而调用fork()的原始进程被称为父进程(Parent Process)

fork() 的返回值

fork() 系统调用的返回值非常重要,因为它可以帮助进程分辨自己是父进程 还是子进程

  • 父进程中返回子进程的 PID :在父进程中,fork() 的返回值是子进程的 PID(一个正整数),这意味着父进程可以知道新创建的子进程的进程标识符。
  • 子进程中返回 0 :在子进程中,fork() 的返回值为0 ,这意味着子进程可以识别自己是由fork()产生的副本。
  • 错误返回值 -1 :如果fork()调用失败,例如系统资源不足时,它会返回 -1,表示进程创建失败。此时,通常需要进行错误处理。
cpp 复制代码
# 执行代码

#include<iostream>
  2 #include <unistd.h>
  3 #include<sys/types.h>
  4 using namespace std;
  5 
  6 
  7 int main()
  8 {
  9     pid_t id = fork();
 10 
 11     if(id == 0)
 12     {
 13         while(true)
 14         {
 15             cout<<"子进程:"<< id << endl;
 16             sleep(5);
 17         }
 18     }
 19     else if(id > 0)
 20     {
 21         while(true)
 22         {
 23             cout<<"父进程:"<< id << endl;
 24             sleep(5);                                                         
 35 	return 0;
 36 }

查看进程:

bash 复制代码
# 执行 每3秒刷新一下进程
while : ; do ps axj | head -1 && ps axj | grep process | grep -v grep ; sleep 3 ;done
    • 两个process 上面进程 PID 23296 下面进程的PPID是 23296
  • 父子进程和的PID是 21346

fork() 被调用时,操作系统会:

  • 操作系统 创建一个新进程(子进程),并复制父进程的地址空间。此时父子进程的地址空间是独立的,但内容完全相同。

  • 虽然父子进程的地址空间是复制的,但现代操作系统通常使用**写时复制(Copy-on-Write)**优化。即只有在进程修改数据时,才真正复制内存。

  • 两个独立的进程在同时独立运行实现了返回值的不同,这就是为什么出现两个返回值。

如何实现区分

  • 操作系统在内核中维护进程表。当 fork() 被调用时,系统为子进程分配一个新的进程表项(即子进程的 PID)。

  • 根据系统调用的上下文,内核可以清楚地知道当前执行的是父进程还是子进程,并返回相应的值。

  • 上述代码 在fork返回值的不同进程之间,数据发生了写时复制通过调用系统上下文对返回值进行确定。

什么出现两个返回值。

如何实现区分

  • 操作系统在内核中维护进程表。当 fork() 被调用时,系统为子进程分配一个新的进程表项(即子进程的 PID)。

  • 根据系统调用的上下文,内核可以清楚地知道当前执行的是父进程还是子进程,并返回相应的值。

  • 上述代码 在fork返回值的不同进程之间,数据发生了写时复制通过调用系统上下文对返回值进行确定。

相关推荐
chenbin52024 分钟前
Jenkins 自动构建Job
运维·jenkins
java 凯25 分钟前
Jenkins插件管理切换国内源地址
运维·jenkins
AI服务老曹29 分钟前
运用先进的智能算法和优化模型,进行科学合理调度的智慧园区开源了
运维·人工智能·安全·开源·音视频
风静如云2 小时前
OpenBMC:BmcWeb定义service
linux
sszdzq2 小时前
Docker
运维·docker·容器
book01212 小时前
MySql数据库运维学习笔记
运维·数据库·mysql
leoufung2 小时前
VIM FZF 安裝和使用
linux·编辑器·vim
bugtraq20213 小时前
XiaoMi Mi5(gemini) 刷入Ubuntu Touch 16.04——安卓手机刷入Linux
linux·运维·ubuntu
xmweisi3 小时前
【华为】报文统计的技术NetStream
运维·服务器·网络·华为认证
VVVVWeiYee3 小时前
BGP配置华为——路径优选验证
运维·网络·华为·信息与通信