网络基础 网络入门基础 | 博客园 1. 计算机网络背景 1. 网络发展 计算机网络的发展是技术迭代与需求驱动共同作用出的历史必然结果,据搜索:可大致分为以下 5 个关键阶段: 1. 起源:军事科研的 “抗毁通信” 需求(20 世纪 60 年代末) 核心事件:1969 年,美国国防部高级研究计划局(ARPA)启动了 ARPANET(阿帕网)项目。当时正值冷战,美国军方需要一种 “去中心化” 的通信网络 —— 即使部分节点被摧毁,其余节点仍能正常通信。 技术特点:ARPANET 最初仅连接了加州大学洛杉矶分校、斯坦福研究院等 4 个节点,采用 “分组交换” 技术(将数据拆分成小数据包传输,提高效率和抗毁性),这是现代网络的核心底层逻辑雏形。 2. 互联基础:TCP/IP 协议的诞生(20 世纪 70 年代) 核心问题:随着网络节点增多,不同网络(如 ARPANET 与其他科研网络)因 “语言不通” 无法互通。 关键突破:1974 年,文顿 ・ 瑟夫(Vinton Cerf)和罗伯特 ・ 卡恩(Robert Kahn)提出了 TCP/IP 协议族(传输控制协议 / 网际协议)。其 ...
深入线程安全:单例、智能指针与同步原语 1. 线程安全的单例模式 1. 什么是设计模式? 设计模式详解:单例、线程安全、反模式 | B 站 设计模式 是一套经过总结、优化的 代码设计经验,它解决的是软件中 可复用性、可维护性、可扩展性 问题。需要注意的是:它不是具体代码,而是解决特定问题的通用模板。 设计模式分为三类: 分类 说明 举例 创建型 处理对象创建 单例、工厂、建造者 结构型 处理类/对象组合 适配器、装饰器、组合、代理 行为型 处理对象交互 观察者、策略、状态机、职责链等 2. 什么是单例模式 定义: 单例模式是一种 创建型设计模式,它保证 某个类在整个程序运行过程中只有一个实例,并提供全局访问点。其核心思想是: 通过私有构造函数和静态实例控制对象创建。 例如:数据库连接池、配置管理类、线程池、日志管理器等,通常用单例实现。 3. 单例模式的特点 唯一性:类只能有一个实例。 全局访问:提供统一的访问接口,无需重复创建对象。 自行实例化:单例类自己负责创建唯一实例。 4. 饿汉 VS 懒汉(实现方式) 吃完饭,立刻洗碗,这种就是饿汉方 ...
Linux
未读线程池与线程封装 1. 线程池 1. ThreadPool.hpp 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191# ...
Linux
未读生产者 - 消费者模型(CP 问题) 1. 生产者-消费者模型(CP 问题)是什么? 这是并发编程中最经典的问题之一,主要描述 两个线程/进程之间的数据交换协作问题: 生产者:不断生产数据,放入缓冲区(仓库、通道)。 消费者:不断从缓冲区中取出数据进行处理。 但问题在于: 缓冲区有 容量限制。 多线程并发会导致 竞争访问资源。 所以需要设计好 同步机制(比如互斥锁、条件变量、信号量等)保证: 生产者不能在缓冲区满的时候继续放; 消费者不能在缓冲区空的时候继续取; 多个线程操作共享资源不会冲突。 2. 什么是“解耦”?为什么要解耦? 1. 解耦的本质 解耦指的是将系统中的不同组件或模块之间的依赖关系降低,使它们能够独立地进行开发、修改和维护。在生产者 - 消费者模型中,解耦就是要让生产者和消费者之间的直接关联尽可能减少,各自可以独立地运行和变化,而不会因为一方的改变对另一方造成过大的影响。简单来说 解耦就是降低模块之间的依赖性,提高系统的可扩展性和灵活性。 在 CP 问题中,供货商和消费者通过缓冲区(超市)进行 间接通信,实现了解耦。 2. 为什么要解耦? 不解耦的弊 ...
Linux
未读深入理解线程间同步与互斥 1. 什么是线程互斥? 简单来说,线程互斥就是当一个线程在访问某个共享资源时,其他线程不能同时访问。就好像多个线程都想去用一台打印机,为了避免打印乱套,得保证同一时间只有一个线程能使用,这就是互斥。 线程互斥 就是为了防止多个线程 同时访问某个共享资源(如变量、文件、临界区),导致数据错误或冲突。 先来看一段代码: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475#include <iostream>#include <stdio.h>#include <pthread.h>#include <vector>#include <string>#include <unistd.h>using namespace std;#define NUM 5 ...
线程控制 1. POSIX 线程库 1. 什么是 POSIX 线程库(pthread) POSIX(Portable Operating System Interface)线程库,又称(简称) pthread(POSIX Threads),是 Unix 系统下的标准化多线程编程接口(IEEE POSIX 标准(IEEE 1003.1c)定义的线程接口)。它提供了一组函数,用于在同一进程内创建、管理和同步多个线程,实现并发和并行处理。 pthread 线程库是应用层的原生线程库: 应用层指的是这个线程库并不是系统接口直接提供的,而是由第三方帮我们提供的。大部分 Linux 系统都会默认带上该线程库(原生的)。与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以 pthread_ 打头的。要使用这些函数库,要通过引入头文件 <pthreaad.h>,链接这些线程函数库时,要使用编译器命令的 -lpthread 选项。 2. 特点 与操作系统紧密集成,性能开销小。 接口统一,可移植性好。 支持线程同步(互斥锁、条件变量)、线程属性设置等丰富功能。 线程共享同一进程的内 ...
线程概念 1. 什么是线程?它和进程的关系? 1. 粒度:执行的“颗粒大小” 粒度(Granularity) 是个比喻术语,表示一个单位在调度或执行上的“精细程度”。举例说明: 进程 是一个较大单位(粗粒度):拥有独立地址空间、资源。 线程 是进程内部的小单位(细粒度):共享地址空间,调度更轻便。 比喻一下:一个公司(进程)可能有多个部门(线程),每个部门是公司内部的执行单位,共享同一个资源(办公室、资金)。 线程执行进程的代码(粒度细) 多线程可以同时执行同一个进程的多个代码分支,这比进程切换效率高。 一个进程内部多个线程共同完成任务,就像车间里多个工人一起干活。 2. 线程的定义 线程是操作系统调度的最小执行单位。 在用户/开发者角度看:线程是进程中的“执行分支”,多个线程可以并发执行进程中的不同任务。 在内核角度看:内核调度的是线程(Linux 称为“轻量级进程”),不是传统意义上的进程。 CPU 视角:只有“执行流”,每个 task_struct(无论是进程还是线程)在 CPU 看来都是“可调度实体”。因此 Linux 把线程干脆叫“轻量级进 ...
Linux
未读进程信号 —— 信号的处理 Linux 进程信号【信号处理】 | CSDN 1. 捕捉/处理信号(进程地址空间) 1. 内核空间与用户空间 每一个进程都有自己的进程地址空间,该进程地址空间由内核空间和用户空间组成: 用户所写的代码和数据位于用户空间,通过用户级页表与物理内存之间建立映射关系。 内核空间存储的实际上是操作系统代码和数据,通过内核级页表与物理内存之间建立映射关系。 内核级页表是一个全局的页表,它用来维护操作系统的代码与进程之间的关系。因此,在每个进程的进程地址空间中,用户空间是属于当前进程的,每个进程看到的代码和数据是完全不同的,但内核空间所存放的都是操作系统的代码和数据,所有进程看到的都是一样的内容。 操作系统本质上就是一个“基于时钟中断的死循环” ,它通过中断机制不断调度任务,实现多任务并发的“假象”。 OS 本身并没有“结束”的时候,它一直在“看有没有事要做”。 它开机后就进入一个大循环:看有没有进程要运行(调度)、看有没有中断发生、处理完后继续循环,这个循环不会退出,除非关机。 时钟中断就像是操作系统的心跳,每隔一段时间就“敲一下操作系统”:“该换人干 ...
Linux
未读进程信号 —— 信号的保存 1. 信号的其他相关概念 概念 含义 例子 信号产生(Generate) 内核决定给进程发送一个信号 比如你按了 Ctrl+C,系统决定给你的程序发一个 SIGINT 信号,就像同事敲了你的门说“有事” 信号未决(Pending) 信号已经产生,但还没被处理,只能排队等着 你正在开会,同事敲了门,但你没理他,他的请求被记下来了,等你有空再处理 信号阻塞(Blocked) 你设置了“我暂时不想处理这些信号” 你提前设置了“开会期间不接电话”,这些信号来了也只能排队等待,不会立刻打断你 信号递达(Delivery) 信号从 pending 状态变为被处理的状态 你开完会,系统发现有一个 SIGINT 在排队,于是开始处理它,触发你设置的处理函数 信号处理(Handler) 你决定怎么处理这个信号(默认、忽略、自定义函数) 你决定怎么处理这个信号:1. 默认处理(系统帮你处理)2. 忽略处理(假装没发生)3. 自定义函数(你写好逻辑来处理) 阻塞 ≠ 忽略 ≠ 未决: 阻塞 是控制递达的时机,信号仍然会记录下来(进入 pend ...
Linux
未读进程信号 —— 信号的产生 首先,本节的信号和上一节的信号量没有任何关系!它们的关系就像老婆饼和老婆,没有任何关系!后面的内容主要是根据 信号的产生 → 信号的保存 → 信号的处理 来进行讲解。 Linux 中的 31 个普通信号 1. 信号的概念 1. 生活中的信号 生活中常见的信号,比如: 闹钟:闹钟响 = 通知你该起床了。 红绿灯:红灯亮 = 告诉你该停下来了。 电话:响铃 = 通知你有人呼叫你,需要你接听。 警报器:火警 = 紧急中断,要求人立刻撤离。 可见,信号本质就是“通知 + 响应”,核心思想是:不需要你一直盯着,只要有事就异步提醒你。 2. 信号的定义与理解 信号是一种 异步通知机制。用来 通知进程 发生了某种 异步事件。本质:操作系统向一个进程发送一个整数编号(信号编号),告诉它“发生了某件事”,要求它“采取行动”或“做出响应”。 Q:你怎么认识这些信号? A:有人教我 → 我记住了。认识:① 识别信号 ② 知道信号的处理方法。即便现在没有信号产生,我们也知道信号产生后该干什么。那么我们是谁?站在 OS 层面,我们自然是进程啦~ 一个进程必须具备识别和 ...











