0%

处理器管理:调度机制与核心算法详解

处理器(CPU)是计算机系统的核心资源,处理器管理的核心目标是合理分配 CPU 时间,确保多个进程高效、有序地并发执行。这一过程涉及调度分级、调度算法、进程状态管理等关键技术,直接影响系统的吞吐量、响应速度和公平性。

处理器调度的三级体系

现代操作系统通过三级调度机制实现对进程生命周期的全流程管理,从作业调入内存到进程获取 CPU,各环节分工明确:

高级调度(作业调度 / 长程调度)

  • 调度对象:外存后备队列中的作业(Job)(作业是用户提交的一个完整任务,包含程序、数据和作业说明书)。
  • 核心功能:
    • 按一定规则从后备队列中选择作业调入内存,为其创建进程、分配初始资源(如内存、文件)。
    • 审查作业资源需求(如内存大小、CPU 时间),判断系统是否有能力满足(避免资源不足导致的运行失败)。
  • 关键数据结构作业控制块(JCB),记录作业的标识、状态、资源需求等信息(如作业名、优先级、估计运行时间)。
  • 适用场景:多道批处理系统(分时 / 实时系统通常不依赖高级调度,因用户交互需快速响应)。

低级调度(进程调度 / 短程调度)

  • 调度对象:内存就绪队列中的进程(Process)
  • 核心功能:
    • 保存现场:将当前运行进程的 CPU 状态(如寄存器值、程序计数器)保存到进程控制块(PCB)。
    • 选择进程:按调度算法从就绪队列中选中下一个运行的进程。
    • 恢复现场:将选中进程的 PCB 信息加载到 CPU,使其继续执行。
  • 调度频率:最高(毫秒级),直接影响系统响应速度。
  • 适用场景:所有操作系统(是处理器管理的核心环节)。

中级调度(内存调度 / 中程调度)

  • 调度对象:内存中暂时无法运行的进程
  • 核心功能:
    • 为提高内存利用率,将 “阻塞状态” 或 “低优先级” 进程换出到外存(称为 “挂起状态”),释放内存资源。
    • 当条件满足时(如阻塞事件结束、内存空闲),将外存中的挂起进程换入内存,转为就绪状态。
  • 本质:通过 “虚拟内存” 技术实现内存与外存的进程交换,逻辑上扩充内存容量。
  • 适用场景:内存资源紧张的系统(如大型服务器、多用户终端)。

三级调度的协同流程

  1. 高级调度:从外存调入作业→创建进程→进入就绪队列。
  2. 低级调度:从就绪队列选进程→分配 CPU 执行。
  3. 中级调度:将暂时无用的进程换出到外存→内存紧张缓解后换入→重新进入就绪队列。
阅读全文 »

操作系统简介:核心功能与系统角色

操作系统(Operating System,OS)是计算机系统中最基础的系统软件,它扮演着 “管理者” 和 “接口” 的双重角色,负责协调计算机硬件与软件资源,为用户和应用程序提供高效、安全的运行环境。本文将从操作系统的目标、作用和核心功能三个维度,系统解析其工作原理。

计算机操作系统的核心目标

操作系统的设计围绕四大核心目标展开,这些目标直接决定了系统的性能和用户体验:

  1. 有效性(Efficiency)
    高效利用计算机资源(CPU、内存、I/O 设备等),减少资源闲置。例如,通过多任务调度让 CPU 同时处理多个程序,通过虚拟内存技术充分利用物理内存,最终提升系统整体吞吐量。
  2. 方便性(Convenience)
    为用户和应用程序提供简洁的交互接口,降低使用计算机的门槛。例如,图形用户界面(GUI)让普通用户无需记忆复杂命令即可操作电脑;系统调用接口让开发者无需直接操作硬件即可实现功能(如文件读写)。
  3. 可扩充性(Extensibility)
    支持功能的模块化扩展,以适应硬件升级和新需求。现代操作系统(如 Linux、Windows)采用分层或微内核架构,新增功能(如新型设备驱动、安全模块)可通过插件形式集成,无需修改核心代码。
  4. 开放性(Openness)
    遵循标准化接口和协议,支持不同厂商的硬件和软件兼容。例如,POSIX 标准确保符合该标准的应用程序可在 Linux、Unix 等系统上通用;USB 接口协议让不同品牌的设备能接入任意计算机。

操作系统的三大核心作用

操作系统是计算机系统的 “中枢神经”,其作用贯穿用户交互、资源管理和抽象封装三个层面:

1. 用户与硬件之间的接口

操作系统为用户提供了三种交互方式,实现 “用户 - 硬件” 的间接通信:

阅读全文 »

Netty 深度解析:从 I/O 模型到核心组件的实战意义

Netty 作为 Java 领域高性能网络编程的事实标准,其设计理念和组件模型深刻影响了分布式系统、中间件等领域的实现。

I/O 模型的演进与 Netty 的选择

三种 I/O 模型的本质差异在于线程与 I/O 操作的交互方式,而 Netty 选择基于 NIO 进行封装,背后是对性能与兼容性的权衡:

维度 BIO(同步阻塞) NIO(同步非阻塞) AIO(异步非阻塞)
线程模型 一连接一线程 单线程处理多连接 操作系统完成后通知线程
适用场景 连接数少、交互简单 高并发、短连接 连接数多、长连接
性能瓶颈 线程切换开销大 需手动处理事件分发 依赖 OS 支持(如 io_uring)
Netty 选择原因 不适用高并发 平衡性能与实现复杂度 兼容性不足(JDK 支持有限)

Netty 为何不选择 AIO?

  • AIO 的异步操作依赖操作系统底层支持,而不同系统(Linux、Windows)的实现差异较大,导致跨平台兼容性差。
  • 高并发场景下,NIO 的 Reactor 模型通过线程池优化,性能可接近 AIO,且可控性更强。

Netty 对 NIO 的改进:从 “能用” 到 “好用”

JDK 原生 NIO 虽提供了多路复用能力,但在实际开发中存在诸多痛点,Netty 的封装解决了这些核心问题:

修复底层缺陷

  • Epoll 空轮询 bug:JDK 7 中的 Selector 会因 epoll 机制缺陷导致无限空轮询,CPU 占用飙升至 100%。Netty 通过 EpollEventLoop 实现自定义轮询逻辑,在检测到空轮询时主动重建 Selector,彻底规避该问题。
  • Buffer 管理优化:JDK 的 ByteBuffer 存在容量固定、复用率低等问题。Netty 提供 ByteBuf 及其内存池实现(PooledByteBufAllocator),通过预分配和复用缓冲区,减少 GC 频率,提升吞吐量。

简化开发复杂度

  • 半包 / 粘包处理:TCP 传输中,数据会因拆包 / 粘包导致接收不完整。Netty 内置LengthFieldBasedFrameDecoder、LineBasedFrameDecoder等编码器,自动处理数据边界问题。

阅读全文 »

Spring Boot 加载自定义 YML 配置文件:从原理到实战

Spring Boot 默认支持 application.yml 配置文件的加载,但在需要拆分配置(如将业务配置与系统配置分离)时,我们常需加载自定义 YML 文件(如 custom.yml)。与 properties 文件不同,自定义 YML 文件无法直接通过 @PropertySource 加载(默认不支持 YML 解析),需通过自定义 PropertySourceFactory 实现。从 “原理分析→实现步骤→实战示例→注意事项” 四个维度,详细讲解自定义 YML 配置的加载方法。

核心问题:为何自定义 YML 无法直接加载?

Spring Boot 的 @PropertySource 注解默认仅支持 properties 格式 的配置文件(通过 DefaultPropertySourceFactory 解析),而 YML 文件采用缩进式语法,需要专用的解析器(如 YamlPropertiesFactoryBean)。

  • properties 文件:键值对格式(key=value),可直接被 @PropertySource 解析;
  • YML 文件:层级结构(key: value),需先转换为键值对格式(如 parent.child=value)才能被 Spring 识别。

因此,加载自定义 YML 文件的核心是:实现一个能将 YML 转换为键值对的 PropertySourceFactory

解决方案:自定义 YML 解析工厂(PropertySourceFactory)

通过自定义 PropertySourceFactory,利用 Spring 内置的 YamlPropertiesFactoryBean 解析 YML 文件,将其转换为 Properties 对象(键值对格式),供 @PropertySource 使用。

1. 实现 YmlPropertySourceFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.lang.Nullable;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* 自定义 YML 配置文件解析工厂,支持 @PropertySource 加载 YML 文件
*/
public class YmlPropertySourceFactory implements PropertySourceFactory {

private static final Logger log = LoggerFactory.getLogger(YmlPropertySourceFactory.class);

@Override
public PropertySource<?> createPropertySource(
@Nullable String name, // 配置源名称(可为 null,自动生成)
EncodedResource resource // 资源对象(包含 YML 文件信息)
) throws IOException {
// 1. 将 YML 文件解析为 Properties 对象(键值对格式)
Properties propertiesFromYaml = loadYamlIntoProperties(resource);

// 2. 处理解析结果(若解析失败,使用默认资源加载方式)
if (propertiesFromYaml == null) {
return (name != null)
? new PropertiesPropertySource(name, resource.getResource())
: new PropertiesPropertySource(resource.getResource().getFilename(), resource.getResource());
}

// 3. 生成配置源名称(优先使用传入的 name,否则使用文件名)
String sourceName = name;
if (!StringUtils.hasText(sourceName)) {
sourceName = resource.getResource().getFilename();
}
if (sourceName == null) {
log.error("无法获取配置文件名称: {}", resource);
throw new RuntimeException("加载 YML 配置文件失败:" + resource);
}

// 4. 返回 Properties 格式的配置源
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
}

/**
* 将 YML 资源解析为 Properties 对象
*/
private Properties loadYamlIntoProperties(EncodedResource resource) {
try {
// 使用 Spring 内置的 YamlPropertiesFactoryBean 解析 YML
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource()); // 设置 YML 资源
factory.afterPropertiesSet(); // 初始化解析器
return factory.getObject(); // 获取解析后的 Properties
} catch (IllegalStateException e) {
log.error("解析 YML 文件失败: {}", resource.getResource().getFilename(), e);
return null;
}
}
}
阅读全文 »

网络层简析

网络层是 OSI 七层模型和 TCP/IP 四层模型中的关键层,其核心作用是实现不同网络之间的数据透明传送,具体包括路由选择、拥塞控制和网际互联等功能。当数据需要从源端发送到接收方时,往往要经过多个中间路由器,因此网络层必须掌握网络拓扑结构(即所有路由器和链路的集合),并从中选择出最优路径。同时,它需要与主机的网络层和传输层进行交互:源主机的网络层通过线缆、光纤等介质将数据传输到远程系统的网络层,随后数据再逐层上移,最终到达远程系统的应用层。

网络层的核心作用

  • 数据分组与寻址:网络层协议定义了如何将数据位和字节组织为更大的分组(称为 “数据包” 或 “数据报”),并规定了统一的寻址机制,使不同计算机能通过该机制相互识别和查找。例如,IP 协议中的 IP 地址就是网络层用于标识主机的关键寻址方式。
  • 跨网络通信支持:支持不同类型的底层网络(如以太网、Wi-Fi、令牌环网等)之间的主机进行对话。无论底层网络采用何种技术,网络层都能屏蔽差异,实现数据的跨网络传输。

网络层提供的服务

网络层主要提供两种服务模式,分别对应不同的协议设计思路:

阅读全文 »