当前位置: 首页 > news >正文

Linux入门学习:进程概念

文章目录

    • 1. 什么是进程?
      • 1.1 基本概念
      • 1.2 task_struct
    • 2. 组织进程
    • 3. 查看进程
      • 3.1 父进程与子进程
      • 3.2 fork创建子进程
      • 3.3 kill
      • 3.4 /proc

1. 什么是进程?

1.1 基本概念

在课本的概念中,进程程序的一个执行实例,正在执行的程序。其内核观点:担当分配系统资源(CPU时间,内存)的实体。但这些概念太笼统,并不能让我们更加清晰的知道进程是什么,实际上,进程是内核数据结构(pcb) + 程序的代码与数据。

pcb(process control block)进程控制块,进程信息被放在一个叫pcb的数据结构中,可以理解为进程属性的集合。在Linux入门学习:深刻理解计算机硬件与OS体系中,我们已经了解到操作系统对我们的硬件进行管理的基本思想----先描述,后组织,pcb就是操作系统用于描述进程的数据结构。

Linux操作系统下的PCB是: task_struct,也就是说Linux描述进程的结构体叫做task_struct,task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。

1.2 task_struct

在Linux系统中,task_struct一般包含以下信息:

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

2. 组织进程

Linux描述完进程task_struct,在内存中,他是怎么将他们组织起来的?答案:是以链表的形式组织起来的!

进程与进程之间:
在这里插入图片描述
在内存中,程序文件一般在磁盘,我们要运行时,先在内存中拷贝一份exe文件,再进程管理的指针中,插入新的task_struct,这个新的task_struct会有成员管理内存中加载的exe,并加载这个exe对应的属性到进程之中。

内存指针: 包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针

在这里插入图片描述

由此,我们可以知道一个事实:我们在Windows双击一个exe文件,把他运行起来,实质上,就是在系统中创建了一个新的进程!在Linux中的,像ls , pwd指令,本质上也是运行了一个exe,创建了一个进程,只不过运行完就直接退出了,而在Windows上的很多软件是常驻进程,一般运行了之后就不会再退出了,没有"运行完"的说法,除非用户直接×掉,直接终止运行。

3. 查看进程

3.1 父进程与子进程

pid – 进程id
ppid – 父进程id

先要明白一个概念:在Linux操作系统中,创建新进程的时候,都是由自己的父进程创建的!!在C语言中,我们可以通过函数getpid与getppid,来查看当前启动的C语言程序的pid与ppid

我们先来观察一个现象:在Linux中写下这样的一段代码

#include <stdio.h>
#include <unistd.h>int main()
{while(1){printf("我是一个进程, 我的pid: %d, ppid, %d\n", getpid(), getppid());}return 0;
}

反复运行后:
在这里插入图片描述

我们发现反复运行后,每次的pid都不一样,但是他们的ppid,每次都是一样的!!为什么?

#查看对应进程的相关信息指令
ps axj | head -1 && ps ajx | grep 进程id

在这里插入图片描述

结论:这些进程的父进程都叫bash!!bash:命令行解释器。在命令行中,我们运行我们自己的可执行程序或者命令行指令本质是bash进程创建的子进程,由子进程 执行我们的代码! !

我们在登录的时候操作系统会自动为我们启动一个bash程序,bash前面有一个-,代表着我们是通过命令行终端进行登录的

3.2 fork创建子进程

在C语言中有一个函数fork,可以借用系统调用,来创建子进程,头文件是<unistd.h>,借此,我们在Linux写一个程序,来先看看现象:

#include <stdio.h>
#include <unistd.h>int main()
{printf("父进程运行: pid: %d, ppid:%d\n", getpid(), getppid());pid_t id = fork();if (id == 0){// 子进程while (1){printf("我是子进程,我的pid: %d, ppid: %d,ret = %d\n", getpid(), getppid(),id);sleep(1);}}else{// 父进程while (1){printf("我是父进程,我的pid: %d, ppid: %d,ret = %d\n", getpid(), getppid(),id);sleep(1);}}return 0;
}

运行之后
在这里插入图片描述

我们可以观察到一个奇怪的现象:为什么if和else的条件同时被满足了?!!竟然同时进行了两个循环?!!毫无疑问的,肯定是程序启动了两个进程,这其中的细节会衍生出很多问题:

Q1:代码中fork返回值是什么?

在这里插入图片描述

 pid_t id = fork();

如果fork成功创建进程,对于父进程的返回值为子进程的pid,子进程的返回值的0。如果创建失败,父进程的返回值为-1。由返回值的不同,满足if或else的不同条件,启动对应的循环。

——》父进程往往只有一个,而子进程往往有多个,给父进程返回子进程的id,是为了方便管理子进程。Linux进程的整体是一个树型结构!!



❓Q2:一个函数(fork)为什么能返回两次?两次的数据还不相同?!

我们的程序在fork之后,毫无疑问,会启动两个程序,这两个程序的关系是父子关系,一般而言,这两个程序的代码是共享的!但是数据是自己保有一份的!!
在这里插入图片描述

——》进程与进程之间是相互独立的! 多个进程之间,运行的时候,即使他们是父子,也不会相互影响,即使其中一个挂了,另一个也能正常运行。对于代码而言,任何进程对代码的权限只是可读的,所以不同的进程使用同一份代码就能得到安全型的保证。但是数据一定是独立的,对于父子进程,fork各自返回了一次,他们得到了各自的数据,各自对自己的数据进行处理,从而启动了不同的循环。

数据是独立的还有一个验证:

	int cnt = 0;if (id == 0){// 子进程while (1){printf("我是子进程,我的pid: %d, ppid: %d,cnt = %d\n,", getpid(), getppid(),cnt);sleep(1);cnt++;}}else{// 父进程while (1){printf("我是父进程,我的pid: %d, ppid: %d,cnt = %d\n", getpid(), getppid(),cnt);sleep(1);}}

在这里插入图片描述

——》观察现象,父进程与子进程的cnt值各不相同。

3.3 kill

对于没有结束的进程,可以用kill指令将其杀掉

 kill -9 进程标示符

在这里插入图片描述

3.4 /proc

/proc目录里面存储文件不在磁盘上,里面的文件都是内存级的,在关机时会消失,开机时又会出现,它是对动态运行的所有进程的一个可视化信息
在这里插入图片描述
蓝色表示的是目录文件,因为一个进程里面可能会存在很多信息,进去看看
在这里插入图片描述
1、其中exe说明当前的进程是可以找到自己要执行的代码的(可视化出来了)。

2、cwd表示的是当前进程的工作目录(current work dir),所以为什么你fopen出来的新文件会被默认放在当前目录,这其实是由该进程的cwd决定的!!

本文就到这里,感谢你看到这里❤️❤️! 我知道一些人看文章喜欢静静看,不评论🤔,但是他会点赞😍,这样的人,帅气低调有内涵😎,美丽大方很优雅😊,明人不说暗话,要你手上的一个点赞😘!

希望你能从我的文章学到一点点的东西❤️❤️


http://www.mrgr.cn/news/35327.html

相关文章:

  • RabbitMQ 在 Linux CentOS 和 Docker 环境下的部署及分布式部署指南
  • 工程化实战内功修炼测试题(二)
  • java:继承题练习
  • 【Unity Bug 随记】unity version control 报 xx is not in a workspace.
  • Swagger enum 最佳实践:深度剖析与应用指南
  • 比ChatGPT更酷的AI工具
  • 计算机复习9.23
  • 【JAVA集合总结-贰】
  • 《深度学习》CNN 数据增强、保存最优模型 实例详解
  • React开发环境搭建以及常见错误解决
  • Mac安装manim
  • 力扣416周赛
  • Java转换流
  • 【深度学习】批量规范化
  • CREO教程——2 绘制标准图纸
  • Footprint Analytics: 我们为何打造 Growthly 这款产品
  • 高等数学大纲
  • vsomeip客户端/服务端大致运行流程
  • 【洛谷】AT_abc371_d [ABC371D] 1D Country 的题解
  • 开源UNI-SOP云统一认证平台
  • 算法:69.x的平方根
  • 深入剖析链表反转:多语言实现与高级语法特性20240924
  • 【环境搭建】MySQL安装部署
  • 04 面部表情识别:Pytorch实现表情识别-表情数据集训练代码
  • 论文研读——《RF-Diffusion: Radio Signal Generation via Time-Frequency Diffusion》
  • Proteus如何添加数码管