单例模式(C语言)
C语言的设计模式(单例模式)
单例模式(Singleton Pattern)是一种设计模式,目的是确保一个类只有一个实例,并提供一个全局访问点。
#include "stdio.h"
#include "stdlib.h"// 定义一个结构体来存储串口配置数据
typedef struct
{int baudRate;int dataBits;int stopBits;} SerialConfig;// 声明一个静态全局变量用于存储单实例
static SerialConfig *serialInstance = NULL;// 获取单实例对象的函数
SerialConfig *getSerialConfigInstance()
{if (serialInstance == NULL){// 如果实例不存在,则创建一个新实例并初始化数据serialInstance = (SerialConfig *)malloc(sizeof(SerialConfig));serialInstance->baudRate = 115200; // 初始化数据serialInstance->dataBits = 8; // 初始化数据serialInstance->stopBits = 1; // 初始化数据}return serialInstance;
}// 释放单实例对象的函数
void freeSerialConfigInstance()
{if (serialInstance != NULL){free(serialInstance);serialInstance = NULL;}
}int main()
{// 获取串口配置的单实例SerialConfig *usart1Config = getSerialConfigInstance();SerialConfig *usart2Config = getSerialConfigInstance();// 打印串口配置的参数printf("Baud Rate: %d\n", usart1Config->baudRate);printf("Data Bits: %d\n", usart1Config->dataBits);printf("Stop Bits: %d\n", usart1Config->stopBits);printf("Baud Rate: %d\n", usart2Config->baudRate);printf("Data Bits: %d\n", usart2Config->dataBits);printf("Stop Bits: %d\n", usart2Config->stopBits);// 释放单实例对象freeSerialConfigInstance();return 0;
}
以上是一个比较具体的例子。但是在多线程中使用的话会出现一些问题:
- 线程安全性:如果在多线程中使用,可能会创建多个实例。因为如果两个线程几乎同时调用
getSerialConfigInstance函数时,他们会同时发现serialInstance为NULL,从而各自创建一个新的实例,这样就违背了单例模式的初衷,导致多个实例的存在。此时需要引入同步机制,比如互斥锁(mutex)来确保线程的安全。
#include "stdio.h"
#include "stdlib.h"
#include "pthread.h"// 定义一个结构体来存储串口配置数据
typedef struct
{int baudRate;int dataBits;int stopBits;} SerialConfig;// 声明一个静态全局变量用于存储单实例
static SerialConfig *serialInstance = NULL;
// 创建互斥锁
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;// 获取单实例对象的函数
SerialConfig *getSerialConfigInstance()
{// 上锁pthread_mutex_lock(&mutex);if (serialInstance == NULL){// 如果实例不存在,则创建一个新实例并初始化数据serialInstance = (SerialConfig *)malloc(sizeof(SerialConfig));serialInstance->baudRate = 115200; // 初始化数据serialInstance->dataBits = 8; // 初始化数据serialInstance->stopBits = 1; // 初始化数据}// 解锁pthread_mutex_unlock(&mutex);return serialInstance;
}// 释放单实例对象的函数
void freeSerialConfigInstance()
{// 上锁pthread_mutex_lock(&mutex);if (serialInstance != NULL){free(serialInstance);serialInstance = NULL;}// 解锁pthread_mutex_unlock(&mutex);
}int main()
{// 获取串口配置的单实例SerialConfig *usart1Config = getSerialConfigInstance();SerialConfig *usart2Config = getSerialConfigInstance();// 打印串口配置的参数printf("Baud Rate: %d\n", usart1Config->baudRate);printf("Data Bits: %d\n", usart1Config->dataBits);printf("Stop Bits: %d\n", usart1Config->stopBits);printf("Baud Rate: %d\n", usart2Config->baudRate);printf("Data Bits: %d\n", usart2Config->dataBits);printf("Stop Bits: %d\n", usart2Config->stopBits);// 释放单实例对象freeSerialConfigInstance();return 0;
}
在这段代码中,pthread_mutex_lock 和 pthread_mutex_unlock 确保了在创建实例的过程中只有一个线程能够访问临界区,从而避免了多个实例的创建。
文章参考:C语言和设计模式(之单件模式)
相关文章:
单例模式(C语言)
C语言的设计模式(单例模式) 单例模式(Singleton Pattern)是一种设计模式,目的是确保一个类只有一个实例,并提供一个全局访问点。 #include "stdio.h" #include "stdlib.h"// 定义一个…...
js前端格式化日期函数
开发需求 在前端中我们通常使用new Date()函数获取到的日期时间是下面这种样子:Thu Jun 06 2024 17:29:11 GMT0800 (中国标准时间),我们想要把它转换成常见的指定格式,比如 年-月-日 时:分:秒年/月/日 时:分:秒年-月-日年/月/日 所以就封装…...
五个超实用的 ChatGPT-4o 提示词
GPT-4o 是 OpenAI 最近推出的最新人工智能模型,不仅具备大语言模型的能力,而且拥有多模态模型的看、读、说等能力,而且速度比 GPT-4 更快。下面我们就来介绍几个超实用的 GPT-4o 提示词,帮助大家更好地了解 GPT-4o 的功能和应用场…...
基于51单片机多功能防盗报警proteus仿真( proteus仿真+程序+设计报告+原理图+讲解视频)
基于51单片机多功能防盗报警系统 1. 主要功能:2. 讲解视频:3. 仿真4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单&&下载链接 基于51单片机多功能防盗报警系统( proteus仿真程序设计报告原理图讲解视频) 仿真图proteus8.9及以上…...
gitee和github的协同
假设gitee上zhaodezan有一个开发库,但是从andeyeluguo上拉取最新的(从github上同步过来最新的) git remote add dbgpt_in_gitee https://gitee.com/andeyeluguo/DB-GPT.git remote -v git pull --rebase dbgpt_in_gitee main 有冲突可能需要…...
压力测试-性能指标-Jmeter使用-压力测试报告
文章目录 1.压测目的2.性能指标3.Jmeter3.1Jmeter使用3.1.1 运行Jmeter3.1.2 添加线程组3.1.3设置HTTP请求3.1.4 设置监视器 3.2 查看Jmeter压测结果3.2.1 查看结果树3.2.2 查看汇总报告3.2.3 查看聚合报告3.2.4 查看汇总图 1.压测目的 内存泄漏:OOM,重…...
通过Slf4j中的MDC实现在日志中添加用户IP功能
一、slf4j中MDC是什么 slf4j除了trace、debug、info、warn、error这几个日志接口外,还可以配合MDC将数据写入日志。换句话说MDC也是用来记录日志的,但它的使用方式与使用日志接口不同。 在使用日志接口时我们一般这么做 log.debug("log debug"…...
代码随想录算法训练营第四十九天| 139.单词拆分、背包问题总结
139.单词拆分 题目链接:139.单词拆分 文档讲解:代码随想录/单词拆分 视频讲解:视频讲解-单词拆分 状态:已完成(0遍) 解题过程 这几天博主忙着面试和入职,一晃已经周四了,这个礼拜…...
STM32F103VE和STM32F407VE的引脚布局
STM32F103VE vs STM32F407VE 引脚对比表 引脚 STM32F103VE STM32F407VE 备注 1 VSS VSS 地 2 VDD VDD 电源 3 VSSA VSSA 模拟地 4 VDDA VDDA 模拟电源 5 OSC_IN OSC_IN 外部时钟输入 6 OSC_OUT OSC_OUT 外部时钟输出 7 NRST NRST 复位 8 PC13 (GPIO) PC13 (GPIO) GPIO 9 PC14 (…...
搜维尔科技:使用 Xsens 动作捕捉技术创建栩栩如生的动画
使用Xsens 动作捕捉技术创建栩栩如生的动画 搜维尔科技:使用 Xsens 动作捕捉技术创建栩栩如生的动画...
鸿蒙开发 一 (三)、ArkTS开发实战上
ArkTS 从 TypeScript 优化而来, 但有些用法又不太一样, 在开发中, 经常会出现一些报错提示,下面我们也汇总一些常见错误,捡一些常见的整理一下 Promise 的用法: //TypeScript 写法:private load…...
TensorRT教程(1)初探TensorRT
1. TensorRT简要介绍 TensorRT(NVIDIA TensorRT)是 NVIDIA 开发的一个用于深度学习推理的高性能推理引擎。它可以针对 NVIDIA GPU 进行高效的深度学习推理加速,提供了许多优化技术,使得推理速度更快,并且可以在生产环境…...
多表连接查询和子查询
一、连接查询 连接查询是SQL语言最强大的功能之一,它可以执行查询时动态的将表连接起来,然后从中查询数据。 1.1、连接两表的方法 在SQL中连接两表可以有两种方法,一种是无连接规则连接,另一种是有连接规则连接。 无连接规则连…...
数据挖掘与机器学习——聚类算法
目录 无监督学习 聚类算法 概念: 功能: 应用场景: 评判标准: 划分聚类: K-means聚类 逻辑实现: 聚类方式 问题: 解决: 可能存在的问题: 1.初始值对K-means聚…...
QT快速下载
去QT官网之后,如下图所示 比如要下载qt-opensource-windows-x86-5.14.2.exe,进入5.14对应的文件夹,找到对应的版本 点击Details, 下载对应的种子,然后通过迅雷下载 个人实测,家庭网络平均18M的速率...
最短路问题
最短路问题是图论里非常经典的一个考点 接下来着重讲述五种求最短路的算法:朴素版dijkstra算法、堆优化版的dijkstra算法、bellman-ford算法、spfa算法、floyd算法 总体思维导图: 总体思路: 最短路分为两大类 { 在以下给出的时间复杂度中n…...
spark MLlib 中的分类模型
理解这些机器学习模型的数学原理需要一定的数学基础,下面我将简要介绍每个模型的数学原理,并附上相关的数学公式。 1. LinearSVC(线性支持向量机) 数学原理: 线性支持向量机的目标是找到一个超平面,最大化…...
24上半年报考人数“不增反降”?备考下半年软考的难了......
近日,工信教考发布了一篇《2024年上半年计算机软件资格考试顺利举行》的文章,公布了2024年上半年软考报考人数共计52.77万人,其中,初级资格5.12万人、中级资格24.37万人、高级资格23.28万人。 软考高级占总报名人数的44%…...
初出茅庐的小李博客之使用立创开发板(ESP32)连接到EMQX Platform【MQTT TLS/SSL 端口连接】
介绍 手上有一块立创开发板,本着不吃灰的原则把它用起来,今天就来用它来连接上自己部署的MQTT服务器进行数据通信。 硬件:立创开发板 开发环境:Arduino IDE Win11 MQTT 平台:EMQX Platform 立创开发板介绍࿱…...
js平滑滚动元素使其可见
直接上重点: let xpath "//*/div[idxxx]"; document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.scrollIntoView({ behavior: "smooth"})这段代码是JavaScript中使用XPath查询文档并执行平…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
