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

【Linux】初识进程(Ⅰ)

1.认识冯诺依曼系统

冯诺依曼体系的核心思想就是存储思想:计算机的程序和程序所处理的数据一样,都以二进制的形式存储在同一个存储器中。

运算器

功能: 负责执行所有的算术运算和逻辑运算。

例子: 加减乘除、与或非比较等操作。

控制器

功能: 是整个计算机的指挥中心。它从存储器中读取指令,进行分析,然后向其他部件发出控制信号,协调各部件步调一致地工作。

运算器 + 控制器 = 中央处理器,也就是我们常说的 CPU。

存储器

功能: 用于存放程序和数据。所有信息(指令和数据)都以二进制形式存储在此。

特点: 这是“存储程序”概念的关键,程序和数据共享同一个存储空间。

例子: 内存(RAM)。

输入设备

功能: 用于将程序和数据输入到计算机中。

例子: 键盘、鼠标、扫描仪等。

输出设备

功能: 用于将计算机处理的结果展示出来。

例子: 显示器、打印机、音响等

关于存取速度:

2. 操作系统

2.1 概念

      操作系统是管理计算机硬件与软件资源的系统软件,是计算机系统的内核与基石。它作为硬件之上的第一层软件,为其他应用程序提供运行基础,并在用户与计算机硬件之间扮演着中介角色。

2.2 功能

操作系统的两大核心职责

  1. 对下管理硬件

    • 任务: 负责高效、公平地管理计算机的所有硬件资源,包括:

      • 处理器(CPU)管理: 决定哪个程序在何时使用CPU(进程调度)。

      • 内存(Memory)管理: 为程序分配和回收内存空间,保证彼此不干扰。

      • 设备(I/O)管理: 驱动并控制键盘、鼠标、显示器、磁盘等外部设备。

      • 文件(File)管理: 以目录树的形式组织磁盘上的数据,负责文件的存储、检索、共享和保护。

  2. 对上提供服务

    • 任务: 通过系统调用(System Calls) 为应用程序提供使用硬件资源的接口,避免了应用程序直接操作硬件的复杂性。同时,它为用户提供了方便操作计算机的接口(如图形界面或命令行)。

3. 进程基础概念

3.1 概念

进程(Process) 是计算机中正在运行的程序的一个实例。它是操作系统进行资源分配和调度的基本单位。

进程是动态的,我理解的就是代码运行的过程。既然如此,那么操作系统是怎么把进程管理起来的呢?

先描述,再组织

我们先来描述进程的所有信息,而要描述一个物体,我们最快想到的应该就是用结构体,从而用这个结构体来表示这个进程,所以操作系统只用管理这些结构体就可以达到管理进程的目的了。

3.2 PCB——描述进程

PCB (Process Control Block):是一个通用概念,是操作系统理论中对于“用来描述和管理进程的数据结构”的统称。这是一个抽象术语。

在Linux下,PCB就是:task_struct结构体

task_struct 是 Linux 内核的⼀种数据结构类型,它会被装载到RAM(内存)并里且包含着进程的信息。所有运行在系统里的进程都以 task_struct 双链表的形式存在内核里。

3.3 查看进程

查看进程就是查看proc这个文件:

命令:ls /proc/

4. 进程状态

进程运行时有不同的状态,为了能够弄清有哪些状态,我们可以看一下在kernel源代码里定义的进程状态:

/*
*The task state array is a strange "bitmap" of
*reasons to sleep. Thus "running" is zero, and
*you can test for combinations of others with
*simple bit tests.
*/static const char *const task_state_array[] = {"R (running)", /*0 */"S (sleeping)", /*1 */"D (disk sleep)", /*2 */"T (stopped)", /*4 */"t (tracing stop)", /*8 */"X (dead)", /*16 */"Z (zombie)", /*32 */};

R(runing):可运行状态。但这并不是只指进程正在 CPU 上执行,而是指进程正在CPU上运行在就绪队列中等待运行

S(sleeping):可中断睡眠状态。进程正在等待某个事件的完成(如等待用户输入、等待网络连接、等待一个信号),在这种状态下睡眠的进程可以被信号中断唤醒

D(deep sleeping):深度睡眠/不可中断睡眠。处于D状态的进程不能被任何信号中断或杀死,即使是kill也不行。这是为了确保进程在等待磁盘操作时不会被打断,从而避免数据不一致或损坏这种内核级别的严重问题。你可能会在系统繁忙等待磁盘时看到这种状态。

T (stopped):停止状态。进程的执行被暂停(挂起),例如:调试器(如 gdb)在设置断点时,会暂停被调试的进程,使其进入此状态。

t (tracing stop): 这是T状态的一个特例,专门表示进程正在被调试器跟踪而停止。例如被 gdb attach 住,在断点处停止

X (dead):进程已经彻底结束死亡,其资源(包括 PCB)都已经被父进程回收。这是一个瞬时状态,你几乎不可能在ps命令中看到它,因为进程一旦终止并回收,就从系统列表中消失了。

Z (zombie):进程已经终止,但其父进程还没有调用wait()来回收它。内核会保留它的进程描述符(PCB)中的一些退出状态信息,直到父进程读取为止。处于这种状态的进程就是“僵尸进程”(Zombie)。如果父进程先退出,这些僵尸进程会被init进程(PID 1)接管并回收。如果大量僵尸进程不回收,会浪费内核的进程表资源。

4.1 查看进程状态

命令: ps aux/axj 命令

• a:显示⼀个终端所有的进程,包括其他用户的进程。

• x:显示没有控制终端的进程,例如后台运行的守护进程。

• j:显示进程归属的进程组ID、会话ID、父进程ID,以及与作业控制相关的信息

• u:以用户为中心的格式显示进程信息,提供进程的详细信息,如用户、CPU和内存使用情况等

下面我们来模拟几个进程的状态,用我们刚学到的命令来查看一下:

4.1.1 查看进程R状态

我现在写了一个死循环的process.c:

将其可执行文件命名为process:

我们可以看到它的R状态,之后我们会解释为什么会有个加号

那么为什么会有第二行的内容呢?因为Linux下一切皆文件,所以我们上面输入grep命令其实也是文件,它运行时也是一个进程,所以我们查找的时候都会查到命令本身,之后我们就直接忽略掉这行就行了

4.1.2 查看进程S状态

写一个需要用户输入数据的程序:

程序会一直等待用户输入,等待输入过程就是S状态

所以此时我们可以看到进程是S状态

4.1.3 查看进程D状态

让系统进入D状态(不可中断睡眠)是一种极其危险的操作,因为它会锁死一个或多个关键进程,甚至可能最终导致整个系统无响应。

所以这里我就不给大家演示了,如果有好奇的小伙伴可以自己问一下AI怎么让进程出现D状态,会有教程的哈,只不过恢复可能就比较麻烦了,实在不行可以重装系统嘛,哈哈哈哈哈

4.1.4 查看进程 t 状态

我在调试程序时打了一个断点,再运行程序,此时程序会在断点处停下

然后我们再查看进程状态,此时是 t 状态

其他状态都不好模拟出来,我们就不演示了

4.2 僵尸进程

4.2.1 僵尸进程的概念

僵尸进程是指已经执行完毕、但其退出状态尚未被父进程收集(读取)的进程。

在进程退出时,操作系统并不会立即清除其所有痕迹,而是会保留一些基本信息(如进程ID、退出状态、运行时间等),直到父进程通过 wait() 或 waitpid() 系统调用来读取这些信息。

下面让我们来创建一个30s的僵尸进程:

运行程序:

查看进程状态:

4.2.2 僵尸进程的危害

浪费系统资源:每个僵尸进程都占用一个进程ID

进程ID耗尽:如果产生大量僵尸进程,可能导致无法创建新进程(系统有最大进程数限制)

系统性能问题:大量的僵尸进程会影响系统性能

如果系统中已经存在僵尸进程,我们该怎么处理呢?

重启父进程:杀死父进程,僵尸进程会被init进程收养并回收,不要尝试杀死僵尸进程,僵尸进程是无法被杀死的。

系统重启:如果僵尸进程太多,最彻底的方法是重启系统

4.3 孤儿进程

孤儿进程是指父进程已经终止或退出,但子进程仍在运行的进程。当一个进程的父进程先于子进程结束时,这些子进程就成为了"孤儿"。

在Unix/Linux系统中,为了解决这个问题,init进程(进程ID为1)会自动收养所有孤儿进程,成为它们的新父进程。

下面我们来创建一个孤儿进程:

运行这个程序:

查看进程状态

前面子进程和父进程都在运行,之后就只有子进程在运行了,此时子进程就是孤儿进程了

5.进程优先级

5.1 基本概念

进程优先级决定了进程获得CPU执行时间的优先顺序。因为CPU资源是有限的,当多个进程都处于可运行状态时,操作系统需要根据优先级来决定哪个进程先使用CPU。

Linux系统下,进程优先级由PRI和NI决定。

5.2 PRI 和 NI

1. PRI (Priority) - 最终优先级

  • 含义:进程实际的优先级,这个值由内核动态调整

  • 范围:通常为 0-139(数值越小,优先级越高)

  • 特点:用户无法直接修改PRI值

2. NI (Nice) - 友好值

  • 含义:用于影响PRI值的修正量

  • 范围:-20 到 19(数值越小,优先级越高)

  • 特点:用户可以通过修改NI值来间接调整进程优先级

进程优先级计算公式:PRI(new) = PRI(old) + NI

5.3 查看系统进程

命令:

ps -l  #查看当前shell进程信息

ps -la #查看所有进程的详情

top

• UID:代表执行者的身份

• PID:代表这个进程的代号

• PPID:代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号

5.4 修改进程优先级

进入top命令:

输入r--> 输入要修改的进程ID号 --> Enter

输入要修改NI值,假如输入10

我们就可以看到PR和NI值都改变了

但是NI值是有范围的,上面也已经说过了

6. 命令行参数和环境变量

6.1 基本概念

命令行参数是程序运行时从命令行传递的参数。

环境变量是系统或用户设置的全局变量,所有进程都可以访问。

6.2 查看命令行参数

下面我们通过一段程序来查看:

参数说明:

argc:参数计数(包括程序名本身)

argv[]:参数值数组(字符串指针数组)

argv[0]:程序名

argv[1] 到 argv[argc-1]:用户传递的参数

编译运行该程序:

6.3 查看环境变量

查看环境变量的方法有很多种,其他方法我们之后再讲,本篇文章我们先通过一段main函数的第三个参数的方式来查看:

编译运行可执行程序:

常用环境变量:

http://www.dtcms.com/a/395432.html

相关文章:

  • VMware登录后没有网络解决方法
  • Infoseek助力品牌公关升级:从成本中心到价值引擎
  • AR 运维系统与 MES、EMA、IoT 系统的融合架构与实践
  • 牛客周赛 Round 110
  • AutoMQ x Lightstreamer: Kafka 金融数据实时分发新方案
  • Vulkan原理到底学什么
  • 第14讲 机器学习的数据结构
  • MATLAB的宽频带频谱感知算法仿真
  • Adobe Fresco下载教程Adobe Fresco 2025保姆级安装步骤(附安装包)
  • MQTT 服务质量 (QoS) 深度解析
  • MySQL EXPLAIN 中的七种 type 类型详解
  • NestJS认识
  • 6.MySQL索引的数据结构【面试题】
  • 【vLLM 最新版v0.10.2】docker运行openai服务与GGUF量化使用方式
  • 鸿蒙开发入门:ArkTS基础与实战
  • #C语言——刷题攻略:牛客编程入门训练(十三):一维数组(二),轻松拿捏!
  • 2.16Vue全家桶-Vuex状态管理
  • 【SSR】SSR 性能问题
  • 《UE教程》第二章第四回——父类蓝图
  • GORM库用法查漏补缺
  • C++11 移动语义与右值
  • FPGA学习笔记——图像处理之对比度调节(直方图均衡化)
  • 如何进行人脸识别
  • 计算机视觉笔试选择题:题组1
  • 第八篇:常量表达式:从const到constexpr的革命
  • RV1126 NO.30:RV1126多线程获取音频AI的PCM数据
  • 基于蚁群算法解决车辆路径问题(VRP)的MATLAB实现
  • C语言自学--C语⾔内存函数
  • 磁带记录仪:从磁带到数字的数据存储之旅
  • 【运维】Ubuntu上WebDAV挂载与自动同步完整指南