【Linux】进程概念(二):PCB,ps 和 fork

📝前言:
上篇文章我们简单介绍了冯诺依曼体系结构和操作系统,这篇文章我们来讲讲进程的基本概念和基本操作

🎬个人简介:努力学习ing
📋个人专栏:Linux
🎀CSDN主页 愚润求学
🌄其他专栏:C++学习笔记C语言入门基础python入门基础C++刷题专栏


一,什么是进程

在Linux操作系统中,进程(Process) 是程序执行时的基本单位,也是系统资源分配和调度的核心对象。

  • 程序 vs 进程
    • 程序:存储在磁盘上的静态可执行文件(如二进制文件或脚本)。
    • 进程:程序被加载到内存并开始执行后的动态实例。一个程序可以对应多个进程(例如同时运行多个vim编辑器)。

进程由:程序代码,数据,进程控制块(PCB)组成
进程 = PCB + 自己的代码和数据

很抽象,我们可以从进程的作用来理解:

进程是操作系统进行资源分配和调度的基本单位。操作系统会为每个进程分配独立的内存空间、CPU 时间片、文件描述符等资源,以确保各个进程能够独立、并发地运行,从而提高系统的资源利用率和处理能力。多个进程可以同时运行在计算机系统中,它们之间可以通过进程间通信(IPC)机制进行数据交换和协同工作,以完成更复杂的任务。


二,PCB

PCB(程序控制块)是操作系统用于管理进程的核心数据结构,包含了进程的各种信息,如进程 ID、进程状态、优先级、资源分配情况等(是进程属性的集合)。
Linux操作系统下的PCB是: 一个名为task_struct的结构体,它会被装载到RAM(内存)里。

task_struct

task_struct中主要包括:

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

进程的组织:所有运⾏在系统⾥的进程都以task_struct链表的形式存在内核⾥。


三,查看进程

ps

ps 命令默认显示的是当前机器(即你正在操作的这台计算机)的进程状态

常用选项:

  • -e:显示所有进程,而不仅仅是与当前终端关联的进程
  • -f:显示进程的详细信息

示例:
在这里插入图片描述

  • UID:启动进程的用户 ID
  • PID :进程标识符
  • PPID:该进程的父进程的 PID
  • C:CPU 使用率
  • STIME:进程的启动时间
  • TTY: 表示进程所关联的终端设备
  • TIME :表示进程自启动以来累计使用 CPU 的时间
  • CMD :显示的是启动该进程所执行的命令,bash 进程,CMD 列显示为 bash,这表明该进程是一个 Bash shell 实例

我们可以发现:

  1. ps -f也是一个进程,也就是说: 我们历史上执行的所有指令,工具,程序,运行起来,全部都是进程
  2. 我们在bash进程(也就是我们这个命令行)所创建的进程的父进程都有bash,os会给每一个登陆用户分配一个bash

当我们在机器上运行一个.c文件(可用while(1)的方式保持一直执行),然后就可以查看到对应的进程:
在这里插入图片描述
可以看到,grep也是一个进程,印证了我们上面的发现1

-axj选项组合

如:
在这里插入图片描述

  • head -1可以输出表头
  • STAT代表进程状态
  • &&;可以分隔多条命令

/proc

进程的信息也可以通过 /proc 系统⽂件夹查看。
/proc 文件夹下,每个进程都有一个以其进程 ID(PID)命名的子目录。
如,查看PID为60592的进程的相关信息目录ls ./proc/60592
在这里插入图片描述

  • cwd:指向进程启动时的当前工作目录(相对路径的起点),创建文件等操作,如果不带路径,就会在cwd这个路径下创建。cd 操作本质上就是调用了 chdir 函数来改变当前cwd
  • exe:可执行文件,当exe被删掉的时候还会有进程是因为:exe已经加载到内存中了,删掉的是磁盘上储存的exe

系统调用进程标识符

系统调用获取进程标识符:getpid()getppid()(都是库函数对系统调用的封装)
在这里插入图片描述
运行结果:
在这里插入图片描述
重新启动进程,会重新想内存加载,pid是会改变的。

杀掉进程

  • Ctrl + c:比如程序在执行while(1)的时候一直刷屏,执行Ctrl + c就是杀掉进程
  • kill -9 + 进程对应的PID:杀掉PID对应的进程,这里的9代表信号

四,创建进程

fork初识

在这里插入图片描述
在这里插入图片描述
fork是复制进程的函数,程序一开始就会产生一个进程,当这个进程(代码)执行到fork()时,fork就会复制一份原来的进程(即就是创建一个新进程,我们称子进程,而原来的进程我们称为父进程),此时父子进程是共存的,他们一起向下执行代码。
即:调用fork函数之后,是两个进程同时执行fork函数之后的代码(拥有各自独立的执行流),而之前的代码已经由父进程执行完毕

fork的返回值:
成功:子进程中返回: 0 ,父进程中返回:子进程 PID。
错误:返回一个-1

子进程和父进程的关系

子进程和父进程的关系是什么呢?

  1. 因为父进程和子进程的关系是:1 : n(一对多),每个子进程只有一个父进程,但是父进程可以有多个子进程,所以父进程需要通过不同的pid区分不同的子进程
  2. 进程具有独立性,即使父进程挂了,子进程也不会挂
  3. 父进程和子进程的代码共享,数据也共享,只有当其中有一个进程要修改数据的时候,底层会进行数据拷贝,子一份,父一份,然后让要修改的目标进程进行修改(写时拷贝,各自私有一份

使用示例

1 简单示例

代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
	int ret = fork();
	printf("hello proc : %d!, ret: %d\n", getpid(), ret);
	sleep(1);
	return 0;
}

运行结果:
在这里插入图片描述
很明显这里fork有两个返回值,一个返回给父进程,一个返回给子进程。第一条打印语句是父进程的执行结果,第二条是子进程的。

具体理解执行过程

这里有一篇文章 fork函数讲解 写的特别好,我就不过多赘述了


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愚润泽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值