进程1111

一、什么是“进程”?——最基础的定义

简单理解:

  • 进程是“正在运行的程序”。可以理解为你在电脑上打开的一个应用(比如微信、浏览器、记事本),运行的这个“实例”就称为一个“进程”。

通俗比喻:

  • 就像你开了一个饭馆,顾客点菜,厨师开始做菜,这一整个操作流程就是一个“服务流程”,这个流程对应的就是一个“进程”。
  • 如果你同时开多个饭馆(多个程序同时运行),它们就是不同的“进程”。

另一个角度:

  • 只“程序”还只是存放在硬盘上的一段代码(静态的,未在运行的状态),但一旦“运转起来”,它就成为了“正在执行中的实体”,这个实体就叫“进程”。

二、为什么要区分“程序”和“进程”

  • 程序(文件)是静态的,存放在硬盘上,是一段代码。
  • 进程是动态的,是程序在“计算机上运行”的状态,包括程序的代码和运行中的数据。

示意:

程序A是一个图片处理软件,它存放在硬盘上;

当你启动它,它变成“正在运行的进程A”,占用CPU和内存。


三、创建一个进程的流程

流程:

  1. 你发出“运行程序”的命令(比如双击软件图标),
  2. 操作系统加载代码到内存中,建立数据结构(PCB),给它赋予ID(PID),
  3. 进入“运行”状态。

生成的过程:

  • 在操作系统中,用户发起命令,操作系统创建一个“进程”实体,启动调度。

四、进程的基本属性(面试中常会问的点)

我们以“面试思维”梳理一下每个属性的作用、细节和涉及的点。

属性 作用/内容 细节
PID(进程ID) 唯一标识一个进程 像身份证号码,系统每创建一个进程就会赋予一个唯一的编号
PPID(父进程ID) 表明这个进程是谁的“孩子” 父进程的PID,用来追溯“关系链”
状态 代表这个进程的当前状况 后续会详细讲
优先级 调度时决定哪个进程先被占用CPU 数字越小优先级越高
程序计数器(PC) 下一条要执行的指令地址 让CPU知道“下一步要操作的指令”在哪
寄存器内容 中间数据储存 进程被“暂停”时,保存“寄存器状态”,恢复后继续

五、进程的状态

这点很关键,很多面试会问你“进程的状态有哪些”,还会问“状态转换的场景”。

1. 运行状态(Running)

  • 进程正在使用CPU运行中(或者在就绪队列等待调度)。
  • 即系统给它分配了CPU时间片,它成功“执行”了指令。

2. 就绪状态(Ready)

  • 进程已准备好运行,等待CPU调度,但目前没有在运行(等待调度器安排时间片);
  • 就像考试前,学生都已经准备好,等待叫号。

3. 阻塞(等待I/O,sleeping)

  • 进程等待某个事件发生(例如数据读取完成、用户输入),暂时不使用CPU;
  • 比如:听歌遇到“等待网络下载”时,进程会阻塞等待。

4. 停止(Stopped)

  • 进程被暂停,比如用命令kill -STOP
  • 类似:老师叫你暂停学习。

5. 僵尸(Zombie)

  • 进程退出了(结束运行),但父进程没读取它的退出信息(没有调用wait()),导致该进程仍然在系统中占位置;
  • 就像:学生毕业了,但老师还没去查成绩,还“挂”在系统里。

六、常见的面试问题(深度剖析)

  1. 什么是“进程”?它和线程有何不同?

    • 进程是程序的一次“运行实例”,线程是进程中的“子任务”或“轻量级进程”。
    • 进程有自己的地址空间,线程共享同一地址空间。但多个线程在一个进程中,通信共享方便,调度成本更低。
  2. 进程是如何创建的?举例说明。

    • 在Unix/Linux中,最常用的是fork():父进程调用后会生成一个“子进程”,子进程是父进程的复制品(包含代码、数据段,但不同的PCB)。

    -fork()返回值:

    • 在父进程返回子进程的PID
    • 在子进程返回0
  3. “死锁”是什么?跟进程有什么关系?

    • 多个进程相互等待对方释放资源,导致无法继续运行。
    • 解决方案:避免环路等待、使用信号量等。
  4. 什么是“僵尸进程”?为什么要避免?

    • 进程退出后,仍在系统中占用资源,等待父进程调用wait()读取退出信息。
    • 僵尸会导致“资源泄露”,长时间累积会崩溃系统。
  5. 父进程先退出,子进程会发生什么?

    • 变成“孤儿进程”,被init(PID=1)“收养”,由它来清理。
  6. 进程切换的原理是什么?它包括哪些内容?

    • 关键是在“上下文切换”:
      • 保存当前进程的寄存器(程序状态)
      • 从PCB恢复下一个要运行的进程的寄存器(恢复上下文)
      • 这就是“切换”发生的本质
  7. “优先级”和“调度策略”关系?

    • 优先级越高(数字越小),越容易获得CPU时间;
    • 调度算法会按照优先级决定进程执行顺序(比如优先轮转、优先级调度、时间片等)。
  8. 你如何观察系统中的所有进程?

    • pstophtop等命令;
    • 查看每个进程的状态、优先级、启动时间、父子关系。

七、更深入的细节(高级面试题重点)

  • 地址空间:

    每个进程有自己虚拟地址空间,用于存放代码、数据、堆、栈。

    虚拟地址到物理地址是由页表控制,确保进程“看似”自己的内存。

  • 写时复制(Copy-On-Write)

    子进程在fork()时通常和父进程共享内存(复制开销大大减小),在写操作时才复制(实现在写时的拷贝)。

  • 调度算法:

    常见有:先来先服务(FCFS)、短作业优先(SJF)、轮转调度(Time Slice)、多级队列、优先级调度等。

  • 进程间通信(IPC):

    包括信号、管道、共享内存、消息队列、信号量等,用来协调进程合作。


八、总结(通俗版攻略)

  • 进程是“正在跑”的程序实例,有ID和状态。
  • 由“创建”函数(如fork())产生,父子关系明确。
  • 状态包括:就绪、运行、阻塞、停止、僵尸。
  • 调度决定谁用CPU,有优先级。
  • 进程的管理和切换,是操作系统的核心技术之一。

最后一点:
面试中除了了解原理,还要熟悉常用命令(pstopkill等)以及常问的“描述进程状态变迁”的场景。

一、虚拟地址空间的“概念大爆炸”

从宏观角度看:

  • 虚拟地址空间就像你在使用电脑时“看到的地址”。它是一块“虚拟的、抽象的空间”,每个进程都有自己看似“独享”的内存空间。

比喻:

  • 就像你在用手机里的地图App,看到的“地图上的地址”对你来说完全清楚,但这实际上是“地图显示”的虚拟地址。
  • 你不知道背后真实的“地理坐标”是在哪,只知道“地图上显示的地点”。

二、虚拟地址空间的结构(详细拆解)

组成部分:

组成部分 作用 具体内容 简单理解
代码段 存放程序代码 运行的指令 动作的“说明书”
数据段 存放已初始化的全局变量 如全局变量初始化的值 变量“的值”
堆(Heap) 动态内存分配区域 new/malloc分配的内存 变化的“暂存区”
栈(Stack) 管理函数调用和局部变量 函数参数、局部变量 快速“存取的区域”

图示理解(简化版):

复制代码

+---------------------------+
|        栈(Stack)        |
|        ...                |
+---------------------------+
|        堆(Heap)         |
|        ...                |
+---------------------------+
|   代码段和数据段        |
+---------------------------+
(地址从低到高递增,具体可以不同系统略有变化)

三、虚拟地址到物理地址的转换——详细解释

核心问题:

“我用虚拟地址访问内存,操作系统是怎么把你看到的地址映射到实际的硬件内存上的呢?”

答案:

通过“页表(Page Table)”这一魔法“映射表”。


四、详细拆解“虚拟地址到物理地址”过程

1. 虚拟地址(VA)

  • 这是每个进程在“运行时看到的地址”。
  • 比如:虚拟地址“0x00400000”。

2. 页(Page)

  • 内存被划分为一块一块的页(Page),每页大小常见为4KB。
  • 地址拆成:
    • 页目录索引(Page Directory Index)
    • 页表索引(Page Table Index)
    • 页内偏移(Offset within the page)

打个比喻:

比如:

  • 你在图书馆找书,虚拟地址就像“书的编号”
  • 图书馆的“书架编号”和“书本位置”相当于页目录和页表

3. 页表(Page Table)

  • 这是操作系统通过硬件支持维护的“映射关系数据库”
  • 它“指示”每个虚拟页对应的实际物理页(Physical Frame)

具体过程:

  • CPU请求去找0x00405000的内容时:
    • 首先,拆解地址,找到对应的虚拟页。
    • 查找页目录和页表,找到对应的物理页帧(Physical Frame Number, PFN)
    • 加上偏移量,就是硬件上的真正物理地址。

简易理解:

虚拟地址有三个部分:

虚拟地址 = [页目录索引][页表索引][偏移]

操作系统和硬件合作:

  • 用“页目录”和“页表”把这些虚拟页映射到真实物理内存(比如:物理页地址是“物理帧编号*页大小”)

五、用人类日常的比喻让你理解

比喻:虚拟地址到物理地址的映射如同:

  • 虚拟地址像你的“房屋门牌号”:比如“101号房”
  • 物理地址像“真正的房子在街上的位置”:比如“在第5排第3户”
  • 页表像“房屋地址簿”:告诉你“101号房”对应的“实际房子地址”

操作系统维护这个“房屋地址簿”,确保每个虚拟地址都能找到对应的实际房子(物理地址)。


六、写时复制(Copy-On-Write)详细讲解(补充)

在你提到“写时复制”的同时,也涉及虚拟地址空间的内容。

  • 公用“页”在fork()后,父子进程最开始共享相同的物理页面(通过页表映射),都指向同一块内存。

  • 写操作发生时(比如子进程要修改数据):

    • 操作系统会“拷贝”这块被共享的物理页面,给写操作的那个进程独享。
    • 这样,两个进程的虚拟地址空间都会保持一致,但实际上,每个进程的“可写”页只有自己拥有。

通俗比喻:

  • 你和朋友共用一本笔记(共享),在你要写的话,会“复印”一份(拷贝),然后你开始自己写。
  • 这样就不会影响到朋友的笔记。

七、总结提炼(让你记得更牢)

  • 虚拟地址空间:每个进程拥有自己“想象中的内存空间”,象征着独立且庞大的“虚拟内存”。
  • 页面(Page):内存的基本划分单位。
  • 页表(Page Table):映射虚拟地址到物理地址的“映射表”。
  • 虚拟地址拆解:页目录索引 + 页表索引 + 偏移(offset)。
  • 写时复制:共享只读的页面,写操作时才复制一份,避免不必要的复制开销。

 

你可能感兴趣的:(linux,运维,服务器)