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

第三篇文档:自助终端全自动生产线 —— 建造者模式封装 System V 信号量完整工程实现

文档定位

核心工程实现,结合设计模式思想,分步构建信号量对象,完整代码、流程拆解、类比、思维导图,可直接用于企业项目。

一、趣味类比:建造者 = 银行自助终端生产线

老式封装:一次性把所有材料塞进机器,无法自定义选配; 建造者模式生产线拆分 4 个独立工序,分步自由配置,最后一键生成完整银行(信号量集):

  1. 工序 1(Builder 初始化):新建空白终端;
  2. 工序 2:选配银行门牌号(key 配置:ftok 私有 / IPC_PRIVATE);
  3. 工序 3:设置窗口总数、每个窗口初始工位;
  4. 工序 4:选配创建权限、标志位(IPC_CREAT/IPC_EXCL);
  5. 工序 5(Director 构建):所有配置完成,一键生成可用银行;
  6. 配套工具:内置 P/V、自动销毁、参数校验、错误捕获。

建造者模式四大角色对应信号量场景

表格

建造者角色对应代码模块银行类比
Product 产品SemProduct完整配置好的银行(信号量实例)
Builder 抽象建造者SemBuilder自助终端标准操作规范(配置接口)
ConcreteBuilder 具体建造者SemConcreteBuilder实际自助终端,实现所有配置步骤
Director 指挥者SemDirector大堂经理,按流程调度配置,生成产品

二、完整可运行建造者模式代码

c

运行

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/sem.h> #include <sys/ipc.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> // ====================== 1. Product 产品:完整信号量实例 ====================== typedef struct { key_t key; int semid; int sem_cnt; int* init_vals; int mode; // 权限 0666 int flag; // IPC_CREAT / IPC_EXCL } SemProduct; // 产品对外操作接口 void sem_product_p(SemProduct* prod, int idx) { struct sembuf op = {idx, -1, 0}; if(semop(prod->semid, &op, 1) == -1) perror("P op fail"); } void sem_product_v(SemProduct* prod, int idx) { struct sembuf op = {idx, 1, 0}; if(semop(prod->semid, &op, 1) == -1) perror("V op fail"); } // 销毁产品,释放内核+堆内存 void sem_product_destroy(SemProduct* prod) { semctl(prod->semid, 0, IPC_RMID); free(prod->init_vals); free(prod); } // ====================== 2. 抽象建造者 Builder ====================== typedef struct SemBuilder SemBuilder; struct SemBuilder { // 分步配置接口 void (*set_key_ftok)(SemBuilder*, const char*, int proj_id); void (*set_key_private)(SemBuilder*); void (*set_sem_count)(SemBuilder*, int cnt); void (*set_single_init)(SemBuilder*, int idx, int val); void (*set_mode_flag)(SemBuilder*, int mode, int flag); // 构建产品 SemProduct* (*build)(SemBuilder*); // 私有缓存配置 SemProduct* temp_prod; }; // ====================== 3. 具体建造者 ConcreteBuilder ====================== void set_key_ftok_impl(SemBuilder* b, const char* path, int proj) { b->temp_prod->key = ftok(path, proj); } void set_key_private_impl(SemBuilder* b) { b->temp_prod->key = IPC_PRIVATE; } void set_sem_count_impl(SemBuilder* b, int cnt) { b->temp_prod->sem_cnt = cnt; free(b->temp_prod->init_vals); b->temp_prod->init_vals = calloc(cnt, sizeof(int)); } void set_single_init_impl(SemBuilder* b, int idx, int val) { if(idx >=0 && idx < b->temp_prod->sem_cnt) b->temp_prod->init_vals[idx] = val; } void set_mode_flag_impl(SemBuilder* b, int mode, int flag) { b->temp_prod->mode = mode; b->temp_prod->flag = flag; } // 核心构建方法:生成可用信号量集 SemProduct* build_impl(SemBuilder* b) { SemProduct* prod = b->temp_prod; // 创建信号量集 prod->semid = semget(prod->key, prod->sem_cnt, prod->flag | prod->mode); if(prod->semid == -1) { perror("semget create fail"); return NULL; } // 逐个初始化信号量初始值 for(int i=0; i<prod->sem_cnt; i++) { semctl(prod->semid, i, SETVAL, prod->init_vals[i]); } // 重置临时缓存,返回成品 SemProduct* ret = malloc(sizeof(SemProduct)); memcpy(ret, prod, sizeof(SemProduct)); ret->init_vals = malloc(sizeof(int)*prod->sem_cnt); memcpy(ret->init_vals, prod->init_vals, sizeof(int)*prod->sem_cnt); return ret; } // 创建具体建造者实例 SemBuilder* create_sem_builder() { SemBuilder* b = malloc(sizeof(SemBuilder)); b->temp_prod = malloc(sizeof(SemProduct)); memset(b->temp_prod, 0, sizeof(SemProduct)); b->temp_prod->init_vals = NULL; // 绑定接口实现 b->set_key_ftok = set_key_ftok_impl; b->set_key_private = set_key_private_impl; b->set_sem_count = set_sem_count_impl; b->set_single_init = set_single_init_impl; b->set_mode_flag = set_mode_flag_impl; b->build = build_impl; return b; } // ====================== 4. Director 指挥者(标准化构建流程) ====================== // 场景1:构建二元互斥信号量(单窗口,初始值1) SemProduct* director_build_mutex(SemBuilder* b, const char* path, int proj) { b->set_key_ftok(b, path, proj); b->set_sem_count(b, 1); b->set_single_init(b, 0, 1); b->set_mode_flag(b, 0666, IPC_CREAT); return b->build(b); } // 场景2:构建私有多窗口计数信号量 SemProduct* director_build_private_sem(SemBuilder* b, int window_num, int init_val) { b->set_key_private(b); b->set_sem_count(b, window_num); for(int i=0; i<window_num; i++) { b->set_single_init(b, i, init_val); } b->set_mode_flag(b, 0600, IPC_CREAT); return b->build(b); } // ====================== 主函数测试演示 ====================== int main() { // 1. 创建建造者生产线 SemBuilder* builder = create_sem_builder(); // 2. 指挥者生成互斥二元信号量 SemProduct* mutex_sem = director_build_mutex(builder, "./test.txt", 0x99); if(!mutex_sem) return -1; printf("建造者生成信号量semid = %d\n", mutex_sem->semid); // 临界区测试 sem_product_p(mutex_sem, 0); printf("获取互斥锁,进入临界区\n"); sleep(2); sem_product_v(mutex_sem, 0); printf("释放互斥锁\n"); // 销毁资源 sem_product_destroy(mutex_sem); free(builder->temp_prod); free(builder); return 0; }

编译运行指令:

bash

运行

touch test.txt gcc sem_builder.c -o sem_builder ./sem_builder ipcs -s # 无残留,代码自动销毁

三、建造者模式工作流程拆解(自助终端流水线)

  1. 初始化空白建造者(空终端);
  2. 自由分步配置 key、窗口数量、初始工位、权限标志;
  3. Director 指挥者封装标准化场景(互斥锁 / 私有计数信号量),业务层无需关心底层配置细节;
  4. 调用 build () 一次性创建内核信号量集并完成初始化,返回完整可用产品;
  5. 产品自带 P/V、销毁接口,业务代码极简。

四、本篇核心思维导图(建造者 + 信号量融合)

五、建造者模式适配 System V 信号量的独特优势

  1. 配置解耦:创建 key、设置信号量数量、初始化 val、权限标志完全分离,按需选配;
  2. 场景复用:Director 封装互斥锁、限流计数、私有 IPC 等通用场景,业务一行代码创建;
  3. 高扩展:后续新增超时 semop、批量操作、信号量查询功能,仅新增 Builder 配置接口,不改动原有业务代码;
  4. 容错统一:所有内核 API 错误捕获统一放在 build 函数内部,业务无需重复写 perror;
  5. 资源自动管理:产品销毁接口统一释放内核信号量 + 堆内存,杜绝 IPC 资源泄露。

六、三篇完整系列总结

  1. 第一篇:吃透 System V 信号量内核原理与原生 API,明白底层银行模型;
  2. 第二篇:发现原生 API 缺陷,实现简易封装,找到耦合痛点;
  3. 第三篇:引入建造者模式分层解耦,工程化封装,标准化生产线,适配企业多并发同步场景。
谢谢
http://www.jsqmd.com/news/1168984/

相关文章:

  • 汽后市场代运营哪个公司服务好?2026 年口碑之选:一灯时代・膜圣科技汽车后市场代运营服务 - GrowthUME
  • 无货源铺货搬家会不会有风险?搬家前先检查标题、图片和类目 - 抖掌柜
  • 飞秋Mac版:让Mac与Windows局域网通信再无隔阂
  • 2026年新媒体运营培训机构多维度深度测评报告 - 教育品牌推荐官
  • 计算机体系结构流水线吞吐率实战:3种瓶颈段优化策略与10指令效率对比
  • 线性变换与相似矩阵不是矩阵等价变形,是同一套主干螺旋变换更换不同观测基底的两种记录形式 -《全域数学vs传统数学:人类文明进阶200讲》第75讲
  • 荆州黄金回收五城实地探访:沙市荆州监利松滋洪湖临街门店全揭秘 - 人间烟火小记
  • 多线程同步误区:volatile 与忙等待的 2 个经典错误案例解析
  • 2026年,揭秘口碑爆棚的江西南昌美术培训企业究竟好在哪! - GrowUME
  • QMCDecode完整指南:轻松破解QQ音乐加密格式,实现跨平台播放自由
  • OpenStack 与 VMware 虚拟化对比:3 大核心差异与 2 种混合云架构选型
  • 2026年常年不缺货稳定供货缠花线生产厂家?:专业推荐精选 - GrowUME
  • 如何快速上手幻兽帕鲁存档编辑工具:5分钟掌握核心技巧
  • 基于先秦道家叠字递归范式的全域双向分形统一场论
  • 2026 年口碑不错的石英管厂家排名|石英管生产领域实力口碑榜单 - 资讯快报
  • 2026 大连易奢福二手香奈儿包包变现攻略,专业鉴定当场打款 - 奢侈品回收实体店
  • 百达翡丽官方保养每次必须更换零件吗的维修解答权威公示(2026年7月最新) - 百达翡丽官方售后中心
  • 终极指南:15分钟用OpCore-Simplify图形化工具搞定黑苹果EFI配置
  • 深入梳理操作系统:分类、功能与全景生态分析
  • 黄金回收的“暗流”藏在哪里?荆州沙市古城监利松滋洪湖五店摸底实录 - 人间烟火小记
  • 5步精通PDF补丁丁:从文档混乱到专业管理的完整指南
  • 九大网盘文件直链下载终极方案:开源工具LinkSwift深度体验指南
  • 高效安全集成:S32K312NHT0VPBST IPW60R099P7 TPS63030DSKR AK7755EN四款进口芯片解锁下一代嵌入式技术
  • 从 1G 到 5G:6 大多址技术演进史与关键性能指标对比
  • 江诗丹顿官方售后服务中心电话与详细地址实地考察报告多信源验证(2026年7月最新) - 江诗丹顿官方服务中心
  • 浪琴中国官方售后服务中心|服务电话及详细地址权威信息通告(2026年7月更新) - 浪琴服务中心
  • 黄金回收的“暗门槛”有多高?黄冈黄州麻城武穴蕲春黄梅五店摸底报告 - 人间烟火小记
  • 2026 年新消息:洪江有实力的睡莲苗种植供应厂家找哪家,别再把睡莲苗扔进泥里了,90%人都做错了这一步。 - 行业甄选官
  • 三步极速下载国家中小学智慧教育平台电子教材:让教育资源触手可及
  • 游戏玩家的终极救星:Playnite如何让你告别多平台切换的噩梦?