【Linux】Linux进程学习(基本认知)

news2024/11/17 10:55:58

在这里插入图片描述
🔥博客主页 小羊失眠啦.
🎥系列专栏《C语言》 《数据结构》 《C++》 《Linux》 《Cpolar》
❤️感谢大家点赞👍收藏⭐评论✍️


在这里插入图片描述

文章目录

  • 前言
  • 一、冯诺依曼体系
  • 二、系统管理
  • 三、进程理解
    • 3.1 代码与数据
    • 3.2 进程控制块
  • 四、查看进程
    • 4.1 ps 指令
    • 4.2 top 指令
    • 4.3 /proc 目录
    • 4.4 父子进程
    • 4.5 小结
  • 五、fork 创建子进程

前言

进程 是计算机中的重要概念,每个运行中的程序都有属于自己的 进程 信息,操作系统可以根据这些信息来进行任务管理,比如在我们Windows中的任务管理器中,可以看到各种运行中的任务信息,这些任务就可以称之为 进程,简单的 进程 二字后面包含着许多知识,比如为什么OS需要对任务进行管理、任务信息是如何组成的、如何创建新任务等,下面我将带大家从 冯诺依曼 结构体系开始,理解学习 进程 相关知识

在这里插入图片描述

一、冯诺依曼体系

我们今天所有的计算机都离不开 冯诺依曼 体系,这位伟大的计算机科学家早在二十世纪四十年代就提出了这种结构,即计算机应由五部分组成:输入设备存储器运算器控制器输出设备

在这里插入图片描述

各组成部分举例:

  • 输入设备:键盘鼠标声卡网卡摄像头
  • 输出设备:显示屏喇叭网卡打印机
  • 存储器:只读存储器随机存取存储器
  • 运算器+控制器:CPU中央处理器

注意: 输入、输出设备 称为外围设备,即 外设,而 外设 一般都会比较慢,比如磁盘;CPU中央处理 的速度是最快的,通过与 存储器 的配合,可以做到高效率处理数据;如果没有 存储器 的存在,那么计算机的整体效率就取决于 外设,正是因为 存储器 的存在,可以对数据进行预加载,CPU 计算时,直接向 存储器 要数据就行了,效率很高。

1957年的今天,冯·诺依曼去世。三句话了解这位“计算机之父”

冯诺依曼 体系的高明之处在于可以大大提高计算机的运算效率,得益于 存储器 这个关键部件

结论:

  • 在数据层面,一般 CPU 不和 外设 直接沟通,而是直接和 内存(存储器) 打交道
    程序必须先加载到 内存 中,这是由硬件体系决定的
  • 外设 只会和 内存 打交道

二、系统管理

有了计算机体系后,就需要 操作系统(OS) 对计算机进行管理,就像一个庞大的学校中会有各种教职工,当然计算器是否好用是很大程度上取决于 操作系统 是否给力

在这里插入图片描述

回归正文,先说结论:操作系统 是一款进行软硬件资源管理的软件

我们普通用户无法直接与计算机中的硬件打交道,也就是说,在没有 操作系统 的情况下,我们几乎是无法使用计算机的,于是一些计算机大牛就创造出了各种好用的 操作系统

举些栗子:

  • 最经典的 Unix 操作系统
  • 我们学习的 Linux 操作系统
  • 市面上流通最广的 Windows 操作系统
  • 高效精致的 Mac 操作系统,基于 Unix
  • 生态丰富的 Android 操作系统,基于 Linux
  • 还有很多操作系统,这里就不一一列举,或许下一个操作系统就由你创造

在这里插入图片描述

操作系统 管理的本质: 先描述,再组织

  • 描述:通过 struct 结构体对各种数据进行描述
  • 组织:通过 链表 等高效的数据结构对数据进行组织管理

比如在 Linux 中是通过 链表 这种数据结构来进行数据组织的

大体逻辑:操作系统 -> 硬件驱动 -> 硬件

具体的逻辑如下图所示:

在这里插入图片描述

我们开发者位于 用户 这一层,开发各种功能,提供给上一层的 用户群体 使用

操作系统的目的:

  • 操作系统 是一个极其庞大的系统,操作系统 通过对下管理好软硬件资源的手段,对上给用户提供良好(安全、稳定、高效、功能丰富等)的执行环境,这是 操作系统 的目的

注意:

  • 操作系统 给我们提供非常良好的服务,并不代表 操作系统 会相信我们,反而,操作系统 不相信任何人

  • 举例理解:就好比银行给我们提供良好的服务,但所有服务都是基于一个小小的柜台窗口,因为银行在为我们提供服务时要确保自身的安全,因此银行的服务是基于 窗口 进行的

  • 操作系统 中也有类似的 窗口,不过它被称为 系统调用,也就是 系统接口

银行办事窗口,商务场景,商务金融,摄影,汇图网www.huitu.com

在这里插入图片描述


三、进程理解

有了 操作系统 相关知识的铺垫后,就可以正式开始介绍 进程

我们可以将 操作系统 的职能分为四大板块

  • 内存管理
  • 进程管理
  • 文件管理
  • 驱动管理

本文探讨的 进程 相关知识属于 进程管理 板块

进程:

  • 我们以前的任何启动并运行程序的行为,都是由 操作系统 帮助我们将程序转换为 进程,然后完成特定任务
  • 一般课本定义:进程 是程序的一个执行实例,是正在执行的程序(这种说法不全面)
  • 正确定义:进程 由两边组成,分别是 相关代码和数据内核关于进程的相关数据结构

也就是说,一个 进程 应该有两部分,数据信息,此处的 信息(进程控制块) 是由 操作系统 对代码和数据进行描述后生成的 信息块 ,原因很简单,方便进行管理,而这就是管理本质的体现: 先描述,再组织

我们对 进程 的相关学习是建立在 进程控制块 上的,上面包含了其对应 进程 的各种信息,下面就来学习一下 数据信息 这两部分知识吧

3.1 代码与数据

数据生万物,任何一个进程都有自己的代码和数据,比如我们常见的 C语言 源文件,经过编译后生成的可执行程序中,就包含着二进制代码和其创建修改的时间、所处位置信息

在这里插入图片描述

在这里插入图片描述

当可执行程序 mytest 运行时,各种数据就会被描述,生成相应的进程控制块

3.2 进程控制块

进程控制块即PCB(process control block)Linux 中的 PCBtask_struct,程序会被描述生成相应的task_struct 装载至 内存

在这里插入图片描述

进程控制块包含内容:

  • 标示符: 描述本进程的唯一标示符,用来区别其他进程

  • 状态: 任务状态,退出代码,退出信号等

  • 优先级: 相对于其他进程的优先级

  • 程序计数器: 程序中即将被执行的下一条指令的地址

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

  • 上下文数据: 进程执行时处理器的寄存器中的数据

  • I/O状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表

  • 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等

  • 其他信息

注: ./可执行程序 其实就是将可执行程序加载至内存中,再执行描述+组织


四、查看进程

我们可以通过指令来查看正在运行中的进程信息

4.1 ps 指令

ps ajx | head -1 && ps ajx | grep 进程名 | grep -v grep

功能: 查看进程信息,其中利用管道进行了信息筛选,使得进程信息更加清晰

在这里插入图片描述

注意: 我们可以通过函数来主动查看进程的 PID

//函数:获取当前进程PID值
#include<unistd.h>
#include<sys/types.h>

pid_t getpid(void);

将程序简单编写下,就可以验证进程块中的进程信息了

#include<stdio.h>
#include<unistd.h>  //Linux中睡眠函数的头文件
#include<sys/types.h>

int main()
{
  int sec = 0;
  while(1)
  {
    printf("这是一个进程,已经运行了%d秒 当前进程的PID为:%zu\n", sec, getpid());
    sleep(1); //单位是秒,睡眠一秒
    sec++;
  }
  return 0;
}

在这里插入图片描述

注: 当程序重新运行后,会生成新的 PID

因为查看进程的指令太长了,所以我们可以结合前面学的自动化构建工具 make ,编写一个 Makefile 文件,文件内容如下所示:

mytest:test.c
     gcc $^ -o $@ -g 
     
.PHONY:clean
clean:
     rm -rf mytest
 
.PHONY:catP
catP:
     ps ajx | head -1 && ps ajx | grep mytest | grep -v grep     

其中的 make catP 指令就是我们刚刚查看 进程 的那一大串指令

在这里插入图片描述

4.2 top 指令

top

这个指令之前有介绍过,相当于Windows中的 ctrl+alt+del 调出任务管理器一样,top 指令能直接调起 Linux 中的任务管理器,显然,任务管理器中包含有进程相关信息

在这里插入图片描述

4.3 /proc 目录

/proc/

在这里插入图片描述

此时可以看出 PID 存在的重要性

4.4 父子进程

进程间存在 父子关系

比如在当前 bash 分支下运行程序,那么程序的 父进程 就是当前 bash 分支

其中,PID 是当前进程的ID,PPID 就是当前进程所属 父进程 的ID
我们一样可以通过函数来查看 父进程 的ID值

//函数:获取当前进程PPID值
#include<unistd.h>
#include<sys/types.h>

pid_t getppid(void);	//用法跟上面的函数完全一样

同样对代码进行小修改,执行指令查看进程信息,可以得到如下结果:

在这里插入图片描述

感兴趣的同学可以去看看 bash 进程的目录中有什么内容

4.5 小结

简单总结一下:

  • 我们可以通过 pstop/proc 查看进程信息
  • 可以利用函数查看当前进程的 PIDPPID
  • 如果指令很长,可以利用 Makefile 文件
  • 进程间存在父子关系,默认进程的父进程为 bash

注:

  • 进程可以创建也可以销毁,通过指令 kill -9 PID 可以销毁指定进程,包括 bash,当然这个指令需要在新的窗口中执行
  • 也可以通过热键 ctrl+c 强制终止当前进程的运行

五、fork 创建子进程

/*
* 创建子进程
* 这个函数有两个返回值
* 进程创建成功时,给父进程返回子进程的PID,给子进程返回0
* 创建失败时,返回 -1
*/
int fork(void)

fork 函数是一个非常重要的函数,它能在当前进程下主动创建 子进程 ,用于程序中
编写代码如下:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>

/*
 * 测试fork创建子进程
 * 理解fork函数的返回值
 * 通过if语句进行分流
 * 总结:fork创建子进程成功时,给父进程返回子进程PID,给子进程返回0,
 如果失败返回-1;通过两次fork可以发现当父进程执行后,才会去执行子进程,
 父子进程间存在独立性,即父进程被kill后,子进程任然可以运行,父子进程间存在写时拷贝机制,
 当子进程的值发生改变时,只会作用于子进程中
 */

int main()
{
  pid_t ret = fork(); //获取返回值
  int val = 1;  //比较值
  if(ret == 0)
  {
    //在子进程内再创建(孙)子进程
    pid_t rett = fork();
    if(rett > 0)
    {
      while(1)
      {
        val = 2;  //写时拷贝
        printf("二代进程正在执行 PID:%d PPID:%d 比较值为:%d 地址:%p\n\n", getpid(), getppid(), val, &val);
        sleep(1);
      }
    }
    else if(rett == 0)
    {
      while(1)
      {
        val = 3;  //写时拷贝
        printf("三代进程正在执行 PID:%d PPID:%d 比较值为:%d 地址:%p\n\n", getpid(), getppid(), val, &val);
        sleep(1);
      }
    }
    else
      printf("进程创建失败\n");
  }
  else if(ret > 0)
  {
      while(1)
      {
        val = 1;  //写时拷贝
        printf("一代进程正在执行 PID:%d PPID:%d 比较值为:%d 地址:%p\n\n", getpid(), getppid(), val, &val);
        sleep(1);
      }
  }
  else
    printf("进程创建失败\n");

  return 0;
}

程序运行结果如下:

在这里插入图片描述

不难发现,子进程 是否出现取决于在当前进程中是否调用 fork 函数

fork函数工作原理:

  • fork 创建子进程时,会新建一个属于 子进程PCB ,然后把 父进程 PCB 的大部分数据拷贝过来使用,两者共享一份代码和数据

各进程间是相互独立的,包括父子进程
这句话的含义是当我们销毁 父进程 后,它所创建的 子进程 并不会跟着被销毁,而是被 init 1号进程接管,成为一个 孤儿进程

具体表现如下:

在这里插入图片描述

fork 创建子进程时还存在 写时拷贝 这种现象,即存在一个全局变量,当父进程的改变值时,不会影响子进程的值,同理子进程也不会影响父进程,再次印证 相互独立 这个现象

在这里插入图片描述

父子进程相互独立的原因:

  • 代码是只读的,两者互不影响
  • 数据:当其中一个执行流尝试修改数据时,OS 会给当前进程触发 写时拷贝 机制

以上只是对 fork 函数的一个简单介绍,关于这个函数底层是如何实现的,是一件较复杂的事,限于篇幅原因,我会在以后对此函数进行补充

简单做个小结
进程小结:

  • bash 命令行解释器本质上也是一个进程,可以被销毁
  • 命令行启动的所有程序,最终都会变成进程,而该进程对应的父进程都是 bash
  • 父进程被销毁后,子进程会变成 孤儿进程
  • 进程间具有独立性,包括父子进程
  • 因为 写时拷贝 机制,父进程不会影响到子进程

程的值,同理子进程也不会影响父进程,再次印证 相互独立 这个现象**

在这里插入图片描述

父子进程相互独立的原因:

  • 代码是只读的,两者互不影响
  • 数据:当其中一个执行流尝试修改数据时,OS 会给当前进程触发 写时拷贝 机制

以上只是对 fork 函数的一个简单介绍,关于这个函数底层是如何实现的,是一件较复杂的事,限于篇幅原因,我会在以后对此函数进行补充

简单做个小结
进程小结:

  • bash 命令行解释器本质上也是一个进程,可以被销毁
  • 命令行启动的所有程序,最终都会变成进程,而该进程对应的父进程都是 bash
  • 父进程被销毁后,子进程会变成 孤儿进程
  • 进程间具有独立性,包括父子进程
  • 因为 写时拷贝 机制,父进程不会影响到子进程

在这里插入图片描述

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

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

相关文章

向量数据库 | AI时代的航道灯塔

向量数据库 | AI时代的航道灯塔 什么是向量检索服务拍照搜商品 你使用过向量数据库吗&#xff1f;使用体验&#xff1f;为什么向量数据库能借由大模型引起众多关注向量数据库在当前AI热潮中是昙花一现&#xff0c;还是未来AI时代的航道灯塔&#xff1f; 今天的话题主要是讨论向…

华清远见STM32MP157开发板助力嵌入式大赛ST赛道MPU应用方向项目开发

第七届&#xff08;2024&#xff09;全国大学生嵌入式芯片与系统设计竞赛&#xff08;以下简称“大赛”&#xff09;已经拉开帷幕&#xff0c;大赛的报名热潮正席卷而来。嵌入式大赛截止今年已连续举办了七届&#xff0c;为教育部认可的全国普通高校大学生国家级A类赛事&#x…

Linux制作C++静态库和动态库并使用示例

创建动态库&#xff1a; 编写源文件&#xff1a; // sub.h 显式调用 #include <iostream>extern "C" int sub(int a, int b);// sub.cpp #include "sub.h"int sub(int a, int b) {return a - b; }// quadrature.h 隐式调用 #include <iostream&…

云服务器centos提示 Cannot prepare internal mirrorlist: No URLs in mirrorlist的解决办法

yum update -y CentOS-8 - AppStream 118 B/s | 38 B 00:00 Error: Failed to download metadata for repo AppStream: Cannot prepare internal mirrorlist: No URLs in mirrorlist 执行下面的命令就可…

LeetCode题练习与总结:合并区间--56

一、题目描述 示例 1&#xff1a; 输入&#xff1a;intervals [[1,3],[2,6],[8,10],[15,18]] 输出&#xff1a;[[1,6],[8,10],[15,18]] 解释&#xff1a;区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].示例 2&#xff1a; 输入&#xff1a;intervals [[1,4],[4,5]] 输出&a…

springCloudAlibaba集成gateWay实战(详解)

一、初识网关&#xff1f; 1、网关介绍 ​ 在微服务架构中&#xff0c;一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f;如果没有网关的存在&#xff0c;我们只能在客户端记录每个微服务的地址&#xff0c;然后分别去调用。这样的话…

我与C++的爱恋:类与对象(一)

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;我与C的爱恋 ​C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&…

【每日力扣】198.打家劫舍与213.打家劫舍II与337.打家劫舍 III

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害 198.打家劫舍 力扣题目链接(opens new window) 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&…

谷歌AI搜索革新:探索高级搜索服务背后的未来趋势

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Redis -- 缓存穿透问题解决思路

缓存穿透 &#xff1a;缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在&#xff0c;这样缓存永远不会生效&#xff0c;这些请求都会打到数据库。 常见的解决方案有两种&#xff1a; 缓存空对象 优点&#xff1a;实现简单&#xff0c;维护方便 缺点&#xff1a; 额外…

STM32之HAL开发——不同系列SPI功能对比(附STM32Cube配置)

不同系列STM32——SPI框图 F1系列框图 F4系列框图 TI模式时序图特性 F7系列框图 H7系列框图 注意&#xff1a;F7系列以及H7系列支持Quad-SPI模式&#xff0c;可以连接单&#xff0c;双或者四条数据线的Flash存储介质。 SPI——Cube配置流程 RCC时钟源配置 SYS系统调试模式配…

【SCI绘图】【箱型图系列1 python】多类对比及各类下属子类对比

SCI&#xff0c;CCF&#xff0c;EI及核心期刊绘图宝典&#xff0c;爆款持续更新&#xff0c;助力科研&#xff01; 本期分享&#xff1a; 【SCI绘图】【箱型图系列1】多类对比各类下属子类对比 文末附带完整代码&#xff1a; 1.环境准备 python 3 from matplotlib import p…

Go语言hash/fnv应用实战:技巧、示例与最佳实践

Go语言hash/fnv应用实战&#xff1a;技巧、示例与最佳实践 引言hash/fnv概览使用hash/fnv的初步步骤导入hash/fnv库创建哈希器实例 hash/fnv在实际开发中的应用生成唯一标识符数据分片与负载均衡快速查找 高级技巧和最佳实践避免哈希碰撞动态调整哈希表大小利用sync.Pool优化哈…

【蓝桥杯】GCD与LCM

一.概述 最大公约数&#xff08;GCD&#xff09;和最小公倍数&#xff08;Least Common Multiple&#xff0c;LCM&#xff09; 在C中&#xff0c;可以使用 std::__gcd(a, b)来计算最大公约数 1.欧几里德算法/辗转相除法 int gcd(int a,int b){return b?gcd(b, a%b):a; } 2…

HTML5动画设计工具 Hype 4 Pro v4.1.14中文激活版

Hype Pro是一款功能丰富、易用且灵活的HTML5动画设计工具&#xff0c;适用于设计师、开发者和创作者创建各种精美的交互式网页动画。它的强大功能和可视化编辑界面使用户能够快速而轻松地实现复杂的动画效果&#xff0c;同时支持多种输出格式和交互方式&#xff0c;满足用户对网…

内网安全之-kerberos协议

kerberos协议是由麻省理工学院提出的一种网络身份验证协议&#xff0c;提供了一种在开放的非安全网络中认证识别用户身份信息的方法。它旨在通过使用秘钥加密技术为客户端/服务端应用提供强身份验证&#xff0c;使用kerberos这个名字是因为需要三方的共同参与才能完成一次认证流…

中科驭数DPU技术开放日秀“肌肉”:云原生网络、RDMA、安全加速、低延时网络等方案组团亮相

2024年3月29日&#xff0c;中科驭数以“DPU构建高性能云算力底座”为主题的线上技术开放日活动成功举办。在开放日上&#xff0c;中科驭数集中展现了其在低时延网络、云原生网络及智算中心网络三大关键场景下的技术成果与五大核心DPU解决方案&#xff0c;凸显了中科驭数在高性能…

RDD算子(四)、血缘关系、持久化

1. foreach 分布式遍历每一个元素&#xff0c;调用指定函数 val rdd sc.makeRDD(List(1, 2, 3, 4)) rdd.foreach(println) 结果是随机的&#xff0c;因为foreach是在每一个Executor端并发执行&#xff0c;所以顺序是不确定的。如果采集collect之后再调用foreach打印&#xf…

使用CSS计数器,在目录名称前加上了序号,让目录看起来更加井然有序

目录&#xff08;Text of Contents缩写为TOC&#xff09;&#xff0c;其实就是一篇文章的概要或简述。这好比&#xff0c;去书店买书&#xff0c;先是被这本书的标题所吸引&#xff0c;而后我们才会&#xff0c;翻开这本书目录&#xff0c;看看这本书主要是在讲些什么&#xff…

Claude 3 on Amazon Bedrock 结合多智能体助力 Altrubook AI 定义消费者 AI 新范式

关于 Altrubook AI 智能消费决策机器人 Altrubook 是全球首创场景化智能决策机器人&#xff0c;由国内外大厂等前员工共同研发&#xff0c;具有定制化 IP 决策机器人、沉浸式购物体验和需求匹配优化等独特优势。目前&#xff0c;Altrubook AI 已完成与 Claude 3 on Amazon Bedr…