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

计算机操作系统 网络入门(小白专版 · 深入浅出)

计算机操作系统 & 网络入门(小白专版 · 深入浅出)


为什么要学习这些?先给个直观比喻

把电脑想象成一个邮局:

  • CPU 是邮局的员工(处理事务的工人);
  • 内存 是邮局里放信件的货架(可以快速拿到);
  • 磁盘(外存) 是外仓库(拿信较慢,需要搬进来);
  • 网络包 是信封,协议 是信封上写的规则(写谁、怎样投递);
  • 中断 就像门铃或报警器,告诉邮局“有新任务/有紧急事儿”。

有了这个比喻,下面的内容都会穿插类比,帮助记忆。


一、中断(Interrupt)与中断处理流程(通俗版)

什么是中断?

  • 当外部设备(键盘、网卡、磁盘)或 CPU 自己发生异常(例如缺页)时,硬件/软件会“打断”当前正在做的事,转而处理紧急事件,这就是中断

中断的分类

  • 硬件中断(Hardware IRQ):网卡、键盘、硬盘控制器触发。
  • 软件中断 / 异常(Exception):除零、缺页(page fault)等由CPU触发。
  • 系统调用(trap):用户程序主动请求内核服务(比如 readwrite)。

中断处理的一般步骤

  1. 保存现场(save context):把寄存器、程序计数器等状态保存到内存(以便处理完能恢复执行)。
  2. 确定原因:读取中断号/异常码,确认是哪种中断。
  3. 运行中断服务程序(ISR / handler):完成最关键的处理(尽量短)。
  4. 恢复现场并返回:把之前保存的寄存器恢复,继续被中断的指令或下一个指令执行。

关键注意(对内核/驱动代码非常重要)

  • 中断上下文不能睡眠/阻塞:不能调用会阻塞的函数(不能 sleep、不能 wait 信号量)——否则系统死锁。
  • 中断处理要做最小工作量:把耗时任务交给“下半部”(bottom half / workqueue / tasklet / deferred work)。
  • 不要在中断里做长时间计算或分配会睡的内存

小例子(键盘中断)

  • 硬件发来中断 → ISR 读取 scancode 放到环形缓冲(ring buffer) → ISR 将“已读”标记后退出 → 用户进程/上半部稍后从缓冲取数据处理。

二、虚拟内存与缺页中断(Page Fault)

为什么要虚拟内存?

  • 程序看到的是连续、独立的地址空间(虚拟地址),操作系统负责把虚拟地址映射到物理内存的“页帧”(frame)。好处:进程隔离、内存共享、地址空间扩展(超过物理内存)等。

页(page)与页表(page table)

  • 常见页大小:4KB(还会有大页如2MB等)。页表保存每个虚拟页与物理页帧的映射,以及状态位(存在/不在、读写权限等)。

什么是缺页中断(page fault)?

  • 当程序访问的虚拟页在页表中标记为“不在内存”(或权限不足),CPU 会触发 缺页异常(特殊的中断/异常),内核负责处理:把所需页从外存(磁盘)读入内存,更新页表,然后重试那条指令。

缺页处理的步骤(简化版)

  1. CPU 触发缺页异常并进入内核。
  2. 内核保存现场并查页表(或反向页表)定位该虚拟页的磁盘地址。
  3. 如果内存已满,选择一个页面进行置换(见下一节)。
  4. 把目标页从磁盘读入空闲内存帧(I/O,可能很慢)。
  5. 更新页表、TLB(必要时刷新)。
  6. 恢复现场,重新执行发生缺页的指令(大多数情况下从这条指令重新开始)。

与一般中断的区别

  • 缺页中断通常会导致相同行指令被重试(重新执行),而不是直接执行下一条指令(这是关键区别)。

类比:你在图书馆找一本书(虚拟页),书不在阅览室(内存)而在外仓(磁盘),你叫管理员帮你从外仓调书(缺页中断),把书放到阅览室后你继续看(恢复指令)。


三、页面置换算法(Page Replacement)

当内存没空帧时,内核要把某页换出(写回磁盘如果需要),常见算法:

  1. FIFO(先进先出)

    • 最先进入内存的页先被置换。实现简单,但可能置换掉当前刚被频繁访问的页(Belady异常)。
  2. LRU(最近最少使用,Least Recently Used)

    • 置换“最近最长时间未被访问”的页面。直觉好,但实现成本高(需要追踪访问时间或用链表)。
  3. Clock(近似LRU)

    • 给每页一个访问位(reference bit),扫描“钟表指针”,如果位为0就换出,为1则清0并跳过。高效且近似LRU。
  4. Optimal(最佳算法)

    • 置换未来最长时间不会被访问的页(理论上最优,但需要未来信息,不可实现,只作参考)。

举例(LRU vs FIFO)

  • 页面访问序列:A B C A B D A B C D,物理帧数 = 3
  • 通过逐步演示可以看到两种算法的缺页次数不同,LRU 通常比 FIFO 更少(但不是绝对)。

## 四、进程上下文 vs 中断上下文(重要)

进程上下文(Process Context)

  • 正常用户进程运行时的内核环境,允许睡眠、阻塞、分配可能阻塞的内存、获取信号量等。

中断上下文(Interrupt Context)

  • CPU 在 ISR 中执行的代码,不能睡、不能阻塞。中断处理程序必须很短。

常见约束(中断上下文必须遵守)

  • 不能执行会导致阻塞/睡眠的 API(例如不能直接调用会等待的文件 I/O、不能 down 一个不可用的信号量)。
  • 不能做长时间工作(应 defer 到下半部)。
  • 不要请求大型内存分配(可能会睡)。
  • 不要调用会引起页错误的函数(因为页错误在中断中处理会复杂化)。

如何把工作分两步做

  • 上半部(Top-half, ISR):快速响应并收集必要数据(如把收到的数据复制到缓冲区),尽快返回中断。
  • 下半部(Bottom-half):在进程上下文或软中断环境执行耗时操作(比如解析数据、磁盘写入等)。Linux 里有 taskletworkqueue 等机制。

五、上下文切换与寄存器(简明)

为何要保存寄存器?

  • 切换线程/进程或进入中断时必须保存当前 CPU 寄存器(PC、SP、一般寄存器)等,以便返回时能继续之前的工作。

上下文切换步骤(概念)

  1. 保存当前进程的寄存器上下文(到进程描述符或内核栈)。
  2. 更新进程状态(就绪/等待等),挑选下一个运行的进程。
  3. 恢复下一个进程的寄存器上下文,跳转执行。

上下文切换会消耗时间(寄存器保存/恢复、TLB 可能失效),因此频繁切换会降低性能。


六、网络基础 — TCP vs UDP(小白理解版)

两者最核心的区别

  • TCP(Transmission Control Protocol):面向连接,可靠、有序、拥塞控制(适合文件传输、HTTP、邮件)。
  • UDP(User Datagram Protocol):无连接、不可靠、不保证顺序,延迟低、开销小(适合实时语音/视频、DNS、一些游戏应用)。

举个场景

  • 发快递(要签收、按顺序到达)→ TCP
  • 发明信片(不保证到达,也不保证先后)→ UDP

UDP 的 connect() 有啥特殊?

  • 调用 connect() 在 UDP 上并不会建立三次握手。它只是把对端 IP/端口记下:

    • 之后 send() 无需每次指定地址,内核只会把数据发到该地址;
    • 内核只会把来自该对端的数据投递到此 socket(相当于“过滤”);
    • 异步错误(如 ICMP 错误)会返回给该 socket。
  • 优点:简化应用逻辑,少些函数参数;缺点:socket 只能与该对端通信(单一对端)。


七、Socket 编程(一个最小的 TCP 服务端/客户端示例 — C++ 风格)

下面给出最简单的示例,解释每一步。注意:这是教学示例,实际生产代码需加错误检查、并发处理、超时处理等。

服务器(伪 C++ / BSD socket):

// 这是示例,不完整的错误处理仅为教学
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);    // 创建 TCP socket
bind(listen_fd, (sockaddr*)&addr, sizeof(addr));   // 绑定 IP 和端口
listen(listen_fd, 5);                               // 开始监听
int client_fd = accept(listen_fd, nullptr, nullptr);// 接受连接(阻塞)
send(client_fd, "Hello\n", 6, 0);                   // 发送数据
close(client_fd); close(listen_fd);

客户端:

int fd = socket(AF_INET, SOCK_STREAM, 0);
connect(fd, (sockaddr*)&server_addr, sizeof(server_addr)); // 建立三次握手
read(fd, buf, sizeof(buf));    // 读取服务器发送的数据
close(fd);

每个函数的直观解释

  • socket():创建一个“邮筒”;
  • bind():把邮筒放在某个门牌(IP:端口);
  • listen():开始排队等候“信件”;
  • accept():把一个排队的连接取出来,得到一个新的连接句柄;
  • connect():客户端向服务器发起连接(触发三次握手);
  • send()/recv() / read()/write():收发数据。

八、TCP 的可靠性(序列号、确认、窗口、重传)

为什么 TCP 可靠?

  • 序列号(Sequence Number):每字节都有序号,接收方通过序号把数据重组成顺序流。
  • 确认(ACK):接收方回送已收到的序号(下一个期待序号)。
  • 重传:若发送方在超时内未收到 ACK,会重传。
  • 滑动窗口(Flow Control):接收方告诉发送方当前还能接收多少字节(窗口大小),避免接收方被淹没。
  • 拥塞控制(Congestion Control):调节发送速率以避免网络拥塞(后面会讲)。

快速重传(Fast Retransmit)

  • 如果接收端连续发送了 3 个相同的 ACK(重复 ACK),发送端通常会认为对应的某个数据段丢失,立即重传而不是等待超时。

## 九、TCP 三次握手(建立连接)与四次挥手(断开连接)

三次握手(为何需要三次?)

  1. 客户端发送 SYN(随机 Seq=X)→ 表示“我想建立连接并给出我的初始序号”。
  2. 服务器回复 SYN+ACK(Seq=Y, Ack=X+1)→ 表示“我同意,给出我的序号,同时确认你的SYN”。
  3. 客户端再发 ACK(Ack=Y+1)→ 确认服务器的SYN,连接建立。

为什么不是两次?

  • 三次握手既能保证双方都能发送也能接收,而且能避免“旧的延迟包”误触发新连接的问题(防止资源浪费与连接错乱)。

四次挥手(连接关闭)

  • TCP 是全双工的:两端都可以独立关闭各自的发送方向。
  • 关闭需要双方分别发送 FIN 和对方确认,因此通常需要 4 次报文(两次 FIN、两次 ACK)。
  • 发起主动关闭的一方会进入 TIME_WAIT(等待 2×MSL,见下)。

TIME_WAIT 与 2×MSL(为什么要等待)

  • MSL = Maximum Segment Lifetime(报文在网络中存在的最大时间)。
  • TIME_WAIT 的目的:确保最后发送的 ACK 能被对端收到(若丢失,对端会重发 FIN),以及防止旧重复的报文(来自已关闭连接)被新连接误解。
  • TIME_WAIT 持续 2 × MSL(实现中通常是系统定值,比如 30s~2min)。

类比:你把信封拿到邮局交给对方并希望对方确认收到了最后一封,你会在门口等一会儿(TIME_WAIT),以便如果对方没收到你能再次确认,或者等过期时间让所有旧邮件从系统中消失。


十、TCP 拥塞控制(慢启动 / 拥塞避免 / 快重传 / 快恢复)

目标:在不精确知道网络容量的前提下,尽量提高吞吐量但不导致网络崩溃。

核心参数

  • cwnd(拥塞窗口):发送端为避免拥塞自行控制的窗口大小(以字节为单位)。
  • ssthresh(慢启动阈值):当 cwnd 超过它后,从指数增长变为线性增长(拥塞避免)。

算法流程(经典版本)

  1. 慢启动(Slow Start):连接开始时 cwnd = 1(或 MSS),每收到一个 ACK cwnd 翻倍(指数增长),直到 cwnd >= ssthresh 或发生丢包。

  2. 拥塞避免(Congestion Avoidance)cwnd 以线性方式增长(每 RTT 增加 1 MSS),避免快速触发拥塞。

  3. 发生丢包(超时):将 ssthresh = cwnd/2,然后把 cwnd 设为 1(回到慢启动)。

  4. 快速重传 + 快速恢复(当收到 3 个重复 ACK)

    • 触发快速重传(立即重传丢失段),将 ssthresh = cwnd/2cwnd = ssthresh + 3*MSS(进入快速恢复以避免退回慢启动太多),随后进入拥塞避免阶段。

小数字示例

  • 初始:cwnd = 1
  • 一个 RTT 后:2 → 再后 48(指数)直到 ssthresh(假设为 16),到 16 后:17, 18, ...(线性)

十一、面试/练习题(建议亲自动手)

  1. 手算题:给出页面访问序列和帧数,模拟 FIFO、LRU,比较缺页数。
  2. 动手题:写一个简单的 TCP 服务端和客户端(上文示例),跑一下 telnetnc 测试连接。
  3. 观察题:用 tcpdump / wireshark 抓包(或 wireshark),观察 TCP 三次握手与四次挥手的报文序列。
  4. 思考题:为什么中断处理不能睡眠?列举两种把耗时处理下放的方法(Linux 中的实现)。

十二、小结(快速回顾)

  • 中断:是硬件/异常通知处理机制,处理要快、不能阻塞。
  • 缺页:是虚拟内存的重要机制,缺页会触发内核来把页调入内存并重试指令。
  • 页面置换:常见有 FIFO、LRU、Clock,选择折中实现效率与开销。
  • 上下文切换:要保存寄存器与状态,有成本。
  • TCP/UDP:TCP可靠重传、顺序、拥塞控制;UDP轻量、低延迟适合实时应用。
  • TCP 建立/关闭:三次握手保证双方能收发并避免旧包;四次挥手与 TIME_WAIT 保护连接正确关闭。
  • 拥塞控制:慢启动、拥塞避免、快速重传/恢复让 TCP 在动态网络中稳定运行。
http://www.dtcms.com/a/439101.html

相关文章:

  • 站长工具seo综合查询外部链接数量商城开发网站
  • STM32电机控制基础知识
  • 算法题(225):樱花
  • 做互联网的网站app客户端网站建设方案
  • 网站描述 关键词上海 有哪些做网站的公司
  • 计算机网络技术电商网站建设与运营方向怎么投放广告
  • 低空经济新纪元:AI驱动的智能无人机技术与应用
  • 专业建站分销商城a wordpress
  • 创建一个顺序栈,并实现基础的“出栈入栈”功能(C++版)
  • 定制手机壳的网站广州冼村旧改最新消息
  • 怎么做淘宝客网站备案网站后台的形成
  • wordpress安装后查看站点失败河北平台网站建设
  • 网站专题页制作网站备案关闭影响排名
  • Python Flask框架深度解析:从入门到高级
  • 网站销售的优势生鲜做的好的网站
  • 中企动力做的网站怎么登陆运城市住房与城乡建设厅网站
  • 香橙派RK3588s部署大模型
  • 【自记】数据开发中分区表、事务表、分区事务表:特性相似处与区别
  • ATMS课程管理系统 - 从零构建的MySQL实战之旅
  • 广东东莞自己建站教程做网站设计的公司叫什么
  • 网站站外引流怎么做西安动力无限网站建设
  • 智能交通顶刊TITS论文分享|一种可以提高车辆轨迹预测精度和稳定性的稀疏时空Transformer模型
  • 福州专业网站设计团队seo排名优化公司
  • 进入WSL2 Ubuntu环境的完整指南
  • 龙岗网站建设公司效果河南建筑官网首页
  • 网站前置审批怎么进网站源码的后台
  • 电商网站建设考试题网站头部优化文字怎么做
  • php做网站有哪些好处界面官方网站
  • perror与stderr:错误处理的“诊断专家“与“急诊通道“
  • 小公司做网站需要什么条件绿茶直播