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

单例模式(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 函数时,他们会同时发现serialInstanceNULL,从而各自创建一个新的实例,这样就违背了单例模式的初衷,导致多个实例的存在。此时需要引入同步机制,比如互斥锁(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_lockpthread_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%&#xf…...

初出茅庐的小李博客之使用立创开发板(ESP32)连接到EMQX Platform【MQTT TLS/SSL 端口连接】

介绍 手上有一块立创开发板,本着不吃灰的原则把它用起来,今天就来用它来连接上自己部署的MQTT服务器进行数据通信。 硬件:立创开发板 开发环境:Arduino IDE Win11 MQTT 平台:EMQX Platform 立创开发板介绍&#xff1…...

js平滑滚动元素使其可见

直接上重点: let xpath "//*/div[idxxx]"; document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.scrollIntoView({ behavior: "smooth"})这段代码是JavaScript中使用XPath查询文档并执行平…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

群晖NAS如何在虚拟机创建飞牛NAS

套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

Python竞赛环境搭建全攻略

Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型&#xff08;算法、数据分析、机器学习等&#xff09;不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...