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

用C语言实现单例模式

单例模式的核心是确保一个类(或模块)只有一个实例,并提供全局访问点。在C语言中,没有类的概念,但可以通过静态变量、函数封装实现类似效果,保证某块内存(如配置对象、管理器)仅被初始化一次。

C语言实现单例模式的关键思路

  1. 隐藏实例:用静态局部变量存储唯一实例(仅在首次访问时初始化)。
  2. 全局访问点:提供一个接口函数,负责初始化实例并返回其指针(确保仅初始化一次)。
  3. 线程安全(可选):在多线程环境下,需通过互斥锁避免并发初始化导致的多实例问题。

示例:配置管理器单例(单线程版)

假设需要一个全局唯一的配置管理器,负责加载和提供配置项(如数据库地址、端口)。

步骤1:定义单例结构体(ConfigManager)
// 配置管理器结构体(单例的具体数据)
typedef struct {char db_host[64];   // 数据库地址int db_port;        // 数据库端口char log_path[128]; // 日志路径
} ConfigManager;
步骤2:实现单例的创建与访问接口

通过静态局部变量存储实例,并用接口函数控制初始化逻辑(仅首次调用时初始化)。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 静态局部变量:存储唯一实例(文件内可见,外部无法直接访问)
static ConfigManager* instance = NULL;// 单例的全局访问接口
ConfigManager* ConfigManager_getInstance() {// 首次调用时初始化实例if (instance == NULL) {instance = (ConfigManager*)malloc(sizeof(ConfigManager));if (instance == NULL) {printf("内存分配失败\n");return NULL;}// 初始化配置(实际场景可能从文件读取)strcpy(instance->db_host, "localhost");instance->db_port = 3306;strcpy(instance->log_path, "/var/log/app.log");printf("配置管理器初始化完成\n");}return instance;
}// 单例的销毁接口(可选,程序退出前调用)
void ConfigManager_destroy() {if (instance != NULL) {free(instance);instance = NULL;printf("配置管理器已销毁\n");}
}
步骤3:使用单例

无论调用多少次ConfigManager_getInstance,返回的都是同一个实例。

int main() {// 第一次获取实例:触发初始化ConfigManager* config1 = ConfigManager_getInstance();printf("数据库地址: %s, 端口: %d\n", config1->db_host, config1->db_port);// 第二次获取实例:直接返回已存在的实例ConfigManager* config2 = ConfigManager_getInstance();printf("日志路径: %s\n", config2->log_path);// 验证是否为同一个实例(地址相同)if (config1 == config2) {printf("config1 和 config2 是同一个实例\n");}// 销毁单例(程序退出前)ConfigManager_destroy();return 0;
}

输出结果

配置管理器初始化完成
数据库地址: localhost, 端口: 3306
日志路径: /var/log/app.log
config1 和 config2 是同一个实例
配置管理器已销毁

多线程安全的单例(加锁版)

在多线程环境中,多个线程可能同时进入instance == NULL的判断,导致创建多个实例。需通过互斥锁保证初始化的原子性。

#include <pthread.h> // 需链接pthread库(编译时加 -lpthread)// 静态实例
static ConfigManager* instance = NULL;
// 互斥锁:保证初始化过程唯一
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;// 线程安全的单例访问接口
ConfigManager* ConfigManager_getInstance() {// 双重检查锁(Double-Checked Locking):减少锁开销if (instance == NULL) { // 第一次检查:避免每次加锁pthread_mutex_lock(&mutex); // 加锁if (instance == NULL) { // 第二次检查:确保仅初始化一次instance = (ConfigManager*)malloc(sizeof(ConfigManager));// ... 初始化配置 ...printf("线程安全的配置管理器初始化完成\n");}pthread_mutex_unlock(&mutex); // 解锁}return instance;
}

核心特点总结

  1. 唯一性:通过静态变量instance确保全局只有一个实例。
  2. 延迟初始化:实例在首次访问时才创建,避免程序启动时的不必要开销。
  3. 封装性:实例通过ConfigManager_getInstance接口访问,外部无法直接修改或创建,保证可控性。
  4. 线程安全(可选):多线程环境下需加锁,双重检查锁可平衡安全性和性能。

C语言的单例模式常用于全局资源管理(如配置、日志、设备驱动),核心是通过静态变量和函数封装控制实例的创建与访问。

http://www.dtcms.com/a/508407.html

相关文章:

  • 怎么样在网站做产品推广设计师设计一套房子要多少钱
  • 网站开发好学seo如何推广网站
  • 基于51单片机温度检测报警
  • LeetCode:210. 课程表 II
  • HYPE模型高级实践:集成多源遥感数据的流域分布式模拟、参数自动率定与模型源代码修改
  • 网站建设网站网页模板开发公司工程部经理岗位职责
  • 学习springBoot框架-开发一个酒店管理系统,来熟悉springboot框架语法~
  • 大数据开发生态及学习路线和应用领域
  • 华为云自助建站好不好网络 网站
  • seo怎么收费网站缺陷和优化的例子
  • 软件产品开发从0到1的各个阶段
  • 设计师个人网站源码知名网站制作
  • dedecms怎么部署网站wordpress动态标签
  • 目标检测:使用自己的数据集微调DEIMv2进行物体检测
  • 揭阳企业建站系统模板服装定制图案
  • 彩票网站和app建设网站开发需要经过的几个主要阶段
  • 如何从零开始:设计一款游戏(从一页纸开始)
  • 小程序简单还是做网站简单前端移动端开发
  • 站长之家官网查询网站开发目录
  • h5游戏免费下载:亡者之城
  • [人工智能-大模型-10]:大模型典型产品对比 - 智能对话与问答​类型
  • 苏州美丽乡村建设网站企业网站带后台模板
  • 淘宝网站制作wordpress怎么更改语言设置
  • 海东企业网站建设公司怎么找推广渠道
  • CSS的hover伪类的元素如何在浏览器开发者工具中被审查!
  • 网站如何做外部链接龙岗网络营销
  • 建设网站要电脑才能吗网站怎样推广 优帮云
  • 一区直接写!CEEMDAN分解 + Informer-LSTM +XGBoost组合预测模型
  • 性价比高的网站建设上海企业网站的建设
  • 合规审核类智能体构建范式