文档定位分析原生 API 开发痛点实现基础面向过程封装引出「分步构建」需求为第三篇建造者模式铺垫。一、趣味类比原生 API 相当于无自助终端的老式银行办业务要手写单据、单独找管理员开门、手动设置窗口工位、走时还要手动关门步骤分散极易漏操作。 企业开发需要标准化自助终端固定流程、参数校验、自动回收资源这就是封装的意义。一、原生 API 五大工程痛点操作分散创建、初始化、P/V、销毁代码散落业务逻辑重复冗余参数易出错sem_num、权限、标志位极易传参错误资源泄露进程异常退出时忘记调用 IPC_RMID内核残留信号量初始化与创建耦合semget 无法直接设置 semval必须额外调用 semctl多信号量集管理混乱多个 key/semid 无统一管理结构。二、基础结构体封装代码面向过程封装封装一个信号量管理器结构体统一存放 key、semid、信号量数量封装全套操作函数c运行#include stdio.h #include sys/sem.h #include sys/ipc.h #include sys/types.h #include unistd.h #include string.h // 统一信号量管理结构体 typedef struct { key_t key; int semid; int sem_count; // 窗口总数 int init_val[]; // 每个窗口初始工位 } SemManager; // 创建管理器分配内存 SemManager* sem_create_mgr(key_t key, int sem_cnt, int init_vals[]) { SemManager* mgr malloc(sizeof(SemManager) sizeof(int)*sem_cnt); mgr-key key; mgr-sem_count sem_cnt; memcpy(mgr-init_val, init_vals, sizeof(int)*sem_cnt); // 创建信号量集 mgr-semid semget(key, sem_cnt, IPC_CREAT | 0666); // 逐个初始化每个窗口 for(int i0; isem_cnt; i) { semctl(mgr-semid, i, SETVAL, init_vals[i]); } return mgr; } // P操作封装 void sem_mgr_p(SemManager* mgr, int idx) { struct sembuf op {idx, -1, 0}; semop(mgr-semid, op, 1); } // V操作封装 void sem_mgr_v(SemManager* mgr, int idx) { struct sembuf op {idx, 1, 0}; semop(mgr-semid, op, 1); } // 销毁释放资源 void sem_mgr_destroy(SemManager* mgr) { semctl(mgr-semid, 0, IPC_RMID); free(mgr); } int main() { key_t key ftok(./test.txt, 0x88); int init[1] {1}; SemManager* mgr sem_create_mgr(key, 1, init); sem_mgr_p(mgr, 0); printf(临界区执行\n); sleep(1); sem_mgr_v(mgr, 0); sem_mgr_destroy(mgr); return 0; }三、封装后依然存在的缺陷引出建造者创建逻辑一次性固化创建、初始化、权限、key 全部写死在一个函数无法灵活选配参数 例如有的场景需要 IPC_EXCL 防止重复创建有的私有 IPC 不需要 ftok现有封装无法灵活切换参数配置耦合严重窗口数量、初始值、权限、key 生成方式全部一次性传入参数过多可读性差无法分步配置业务需要先指定 key再设置窗口数再单独配置每个窗口初始值最后构建实例现有封装只能一次性传入所有参数扩展性差新增超时阻塞、批量 semop 操作时需要大量修改创建函数。四、本篇思维导图五、本篇小结基础封装解决了代码冗余但灵活性不足配置逻辑全部耦合在创建函数。我们需要一种分步配置、最后统一生成完整信号量实例的设计模式 —— 建造者模式第三篇实现 System V 信号量专属建造者工程封装。谢谢
第二篇文档:改造杂乱银行 —— 信号量通用封装类与工程痛点分析
发布时间:2026/7/12 5:03:11
文档定位分析原生 API 开发痛点实现基础面向过程封装引出「分步构建」需求为第三篇建造者模式铺垫。一、趣味类比原生 API 相当于无自助终端的老式银行办业务要手写单据、单独找管理员开门、手动设置窗口工位、走时还要手动关门步骤分散极易漏操作。 企业开发需要标准化自助终端固定流程、参数校验、自动回收资源这就是封装的意义。一、原生 API 五大工程痛点操作分散创建、初始化、P/V、销毁代码散落业务逻辑重复冗余参数易出错sem_num、权限、标志位极易传参错误资源泄露进程异常退出时忘记调用 IPC_RMID内核残留信号量初始化与创建耦合semget 无法直接设置 semval必须额外调用 semctl多信号量集管理混乱多个 key/semid 无统一管理结构。二、基础结构体封装代码面向过程封装封装一个信号量管理器结构体统一存放 key、semid、信号量数量封装全套操作函数c运行#include stdio.h #include sys/sem.h #include sys/ipc.h #include sys/types.h #include unistd.h #include string.h // 统一信号量管理结构体 typedef struct { key_t key; int semid; int sem_count; // 窗口总数 int init_val[]; // 每个窗口初始工位 } SemManager; // 创建管理器分配内存 SemManager* sem_create_mgr(key_t key, int sem_cnt, int init_vals[]) { SemManager* mgr malloc(sizeof(SemManager) sizeof(int)*sem_cnt); mgr-key key; mgr-sem_count sem_cnt; memcpy(mgr-init_val, init_vals, sizeof(int)*sem_cnt); // 创建信号量集 mgr-semid semget(key, sem_cnt, IPC_CREAT | 0666); // 逐个初始化每个窗口 for(int i0; isem_cnt; i) { semctl(mgr-semid, i, SETVAL, init_vals[i]); } return mgr; } // P操作封装 void sem_mgr_p(SemManager* mgr, int idx) { struct sembuf op {idx, -1, 0}; semop(mgr-semid, op, 1); } // V操作封装 void sem_mgr_v(SemManager* mgr, int idx) { struct sembuf op {idx, 1, 0}; semop(mgr-semid, op, 1); } // 销毁释放资源 void sem_mgr_destroy(SemManager* mgr) { semctl(mgr-semid, 0, IPC_RMID); free(mgr); } int main() { key_t key ftok(./test.txt, 0x88); int init[1] {1}; SemManager* mgr sem_create_mgr(key, 1, init); sem_mgr_p(mgr, 0); printf(临界区执行\n); sleep(1); sem_mgr_v(mgr, 0); sem_mgr_destroy(mgr); return 0; }三、封装后依然存在的缺陷引出建造者创建逻辑一次性固化创建、初始化、权限、key 全部写死在一个函数无法灵活选配参数 例如有的场景需要 IPC_EXCL 防止重复创建有的私有 IPC 不需要 ftok现有封装无法灵活切换参数配置耦合严重窗口数量、初始值、权限、key 生成方式全部一次性传入参数过多可读性差无法分步配置业务需要先指定 key再设置窗口数再单独配置每个窗口初始值最后构建实例现有封装只能一次性传入所有参数扩展性差新增超时阻塞、批量 semop 操作时需要大量修改创建函数。四、本篇思维导图五、本篇小结基础封装解决了代码冗余但灵活性不足配置逻辑全部耦合在创建函数。我们需要一种分步配置、最后统一生成完整信号量实例的设计模式 —— 建造者模式第三篇实现 System V 信号量专属建造者工程封装。谢谢