单例模式(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语言和设计模式(之单件模式)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值