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

云南昆明网站建设公司蚌埠本地网站

云南昆明网站建设公司,蚌埠本地网站,网站建设费用计入管理费用,互联网软件开发工资一般多少文章目录 C语言发布订阅模式详解与实践1. 什么是发布订阅模式?2. 为什么需要发布订阅模式?3. 实际应用场景4. 代码实现4.1 UML 关系图4.2 头文件 (pubsub.h)4.3 实现文件 (pubsub.c)4.4 使用示例 (main.c) 5. 代码分析5.1 关键设计点5.2 实现特点 6. 编译…

文章目录

  • C语言发布订阅模式详解与实践
    • 1. 什么是发布订阅模式?
    • 2. 为什么需要发布订阅模式?
    • 3. 实际应用场景
    • 4. 代码实现
      • 4.1 UML 关系图
      • 4.2 头文件 (pubsub.h)
      • 4.3 实现文件 (pubsub.c)
      • 4.4 使用示例 (main.c)
    • 5. 代码分析
      • 5.1 关键设计点
      • 5.2 实现特点
    • 6. 编译和运行
    • 7. 注意事项
    • 8. 改进建议
    • 9. 总结
    • 参考资料

C语言发布订阅模式详解与实践

1. 什么是发布订阅模式?

发布订阅模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题。这个主题在状态发生变化时,会通知所有依赖于它的订阅者对象,使它们能够自动更新。

2. 为什么需要发布订阅模式?

  • 实现对象间的松耦合
  • 支持广播通信
  • 动态订阅和取消订阅
  • 事件驱动架构
  • 异步消息处理

3. 实际应用场景

  • 传感器数据分发
  • 消息队列系统
  • 事件处理系统
  • 日志监控
  • 状态更新通知

4. 代码实现

4.1 UML 关系图

Publisher
+publish()
+subscribe()
+unsubscribe()
Subscriber
+update()
Topic
+name
+data

4.2 头文件 (pubsub.h)

#ifndef PUBSUB_H
#define PUBSUB_H#include <stdint.h>
#include <stdbool.h>// 主题数据结构
typedef struct {char name[32];          // 主题名称void* data;            // 主题数据uint32_t data_size;    // 数据大小uint32_t timestamp;    // 时间戳
} Topic;// 订阅者回调函数类型
typedef void (*SubscriberCallback)(const Topic* topic, void* user_data);// 订阅者结构
typedef struct {char name[32];              // 订阅者名称SubscriberCallback callback; // 回调函数void* user_data;            // 用户数据
} Subscriber;// 发布者结构
typedef struct {char name[32];              // 发布者名称Subscriber* subscribers[16]; // 订阅者列表int subscriber_count;       // 订阅者数量
} Publisher;// 创建发布者
Publisher* create_publisher(const char* name);// 销毁发布者
void destroy_publisher(Publisher* publisher);// 订阅主题
bool subscribe(Publisher* publisher, const char* subscriber_name,SubscriberCallback callback,void* user_data);// 取消订阅
bool unsubscribe(Publisher* publisher, const char* subscriber_name);// 发布主题
void publish(Publisher* publisher, const Topic* topic);#endif // PUBSUB_H

4.3 实现文件 (pubsub.c)

#include "pubsub.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>Publisher* create_publisher(const char* name) {Publisher* publisher = (Publisher*)malloc(sizeof(Publisher));strncpy(publisher->name, name, sizeof(publisher->name) - 1);publisher->subscriber_count = 0;memset(publisher->subscribers, 0, sizeof(publisher->subscribers));return publisher;
}void destroy_publisher(Publisher* publisher) {if (!publisher) return;// 释放所有订阅者for (int i = 0; i < publisher->subscriber_count; i++) {free(publisher->subscribers[i]);}free(publisher);
}bool subscribe(Publisher* publisher, const char* subscriber_name,SubscriberCallback callback,void* user_data) {if (!publisher || !subscriber_name || !callback) return false;// 检查是否已达到最大订阅者数量if (publisher->subscriber_count >= 16) {printf("订阅者数量已达上限\n");return false;}// 检查是否已订阅for (int i = 0; i < publisher->subscriber_count; i++) {if (strcmp(publisher->subscribers[i]->name, subscriber_name) == 0) {printf("订阅者 %s 已存在\n", subscriber_name);return false;}}// 创建新订阅者Subscriber* subscriber = (Subscriber*)malloc(sizeof(Subscriber));strncpy(subscriber->name, subscriber_name, sizeof(subscriber->name) - 1);subscriber->callback = callback;subscriber->user_data = user_data;// 添加到订阅者列表publisher->subscribers[publisher->subscriber_count++] = subscriber;printf("订阅者 %s 已添加\n", subscriber_name);return true;
}bool unsubscribe(Publisher* publisher, const char* subscriber_name) {if (!publisher || !subscriber_name) return false;for (int i = 0; i < publisher->subscriber_count; i++) {if (strcmp(publisher->subscribers[i]->name, subscriber_name) == 0) {// 释放订阅者free(publisher->subscribers[i]);// 移动后续订阅者for (int j = i; j < publisher->subscriber_count - 1; j++) {publisher->subscribers[j] = publisher->subscribers[j + 1];}publisher->subscriber_count--;printf("订阅者 %s 已移除\n", subscriber_name);return true;}}printf("未找到订阅者 %s\n", subscriber_name);return false;
}void publish(Publisher* publisher, const Topic* topic) {if (!publisher || !topic) return;printf("\n发布者 %s 发布主题 %s\n", publisher->name, topic->name);// 通知所有订阅者for (int i = 0; i < publisher->subscriber_count; i++) {Subscriber* subscriber = publisher->subscribers[i];printf("通知订阅者 %s\n", subscriber->name);subscriber->callback(topic, subscriber->user_data);}
}

4.4 使用示例 (main.c)

#include "pubsub.h"
#include <stdio.h>// 温度传感器订阅者回调
void temperature_callback(const Topic* topic, void* user_data) {float* threshold = (float*)user_data;float temperature = *(float*)topic->data;printf("温度传感器收到数据: %.1f°C\n", temperature);if (temperature > *threshold) {printf("警告:温度超过阈值 %.1f°C!\n", *threshold);}
}// 日志记录订阅者回调
void logger_callback(const Topic* topic, void* user_data) {printf("日志记录器:主题 %s, 数据大小 %d, 时间戳 %d\n",topic->name, topic->data_size, topic->timestamp);
}int main() {// 创建发布者Publisher* sensor_publisher = create_publisher("传感器发布者");// 创建温度阈值float temp_threshold = 30.0f;// 订阅主题subscribe(sensor_publisher, "温度监控器", temperature_callback, &temp_threshold);subscribe(sensor_publisher, "系统日志", logger_callback, NULL);// 创建并发布温度数据float temp_data[] = {25.5f, 28.3f, 32.7f};for (int i = 0; i < 3; i++) {Topic topic = {.name = "temperature",.data = &temp_data[i],.data_size = sizeof(float),.timestamp = (uint32_t)time(NULL)};publish(sensor_publisher, &topic);}// 取消订阅unsubscribe(sensor_publisher, "系统日志");// 再次发布数据float final_temp = 35.2f;Topic topic = {.name = "temperature",.data = &final_temp,.data_size = sizeof(float),.timestamp = (uint32_t)time(NULL)};publish(sensor_publisher, &topic);// 清理资源destroy_publisher(sensor_publisher);return 0;
}

5. 代码分析

5.1 关键设计点

  1. 发布者管理订阅者列表
  2. 回调机制实现通知
  3. 主题数据封装
  4. 动态订阅管理

5.2 实现特点

  1. 函数指针实现回调
  2. 支持用户数据传递
  3. 订阅者管理完善
  4. 资源管理安全

6. 编译和运行

gcc -c pubsub.c -o pubsub.o
gcc -c main.c -o main.o
gcc pubsub.o main.o -o pubsub_demo

7. 注意事项

  1. 订阅者数量限制
  2. 内存管理安全
  3. 回调函数异常处理
  4. 线程安全考虑

8. 改进建议

  1. 添加主题过滤
  2. 实现异步通知
  3. 支持优先级订阅
  4. 添加订阅者分组

9. 总结

发布订阅模式通过解耦发布者和订阅者,实现了灵活的消息通知机制。这种模式特别适合处理事件驱动的场景。

参考资料

  1. 《设计模式:可复用面向对象软件的基础》
  2. 《C语言程序设计》
  3. 《事件驱动编程》

文章转载自:

http://tijNlGVQ.zztkt.cn
http://eIWmRt5g.zztkt.cn
http://bq3k39xX.zztkt.cn
http://0B5ACmN9.zztkt.cn
http://V4FiveOf.zztkt.cn
http://1rE2WYSz.zztkt.cn
http://JiijCiIW.zztkt.cn
http://BRuxWc56.zztkt.cn
http://GPnVcb1T.zztkt.cn
http://yXyfaElq.zztkt.cn
http://rf6JxuHj.zztkt.cn
http://0ECIjLtC.zztkt.cn
http://2pPMRQOD.zztkt.cn
http://Yk5XOq0f.zztkt.cn
http://i7wrtBFj.zztkt.cn
http://mFc2KeCL.zztkt.cn
http://Ivc2Kl3W.zztkt.cn
http://ryN6yNJD.zztkt.cn
http://84MURUgB.zztkt.cn
http://TWq5JFK5.zztkt.cn
http://gFR2TFwW.zztkt.cn
http://LjqOB3S3.zztkt.cn
http://TkR1gfAN.zztkt.cn
http://S1YJMhvn.zztkt.cn
http://4bYPCOkq.zztkt.cn
http://KZkegIGw.zztkt.cn
http://TQC2D0PE.zztkt.cn
http://z018Tfzv.zztkt.cn
http://n6Y9SpOU.zztkt.cn
http://QmSfF1Wy.zztkt.cn
http://www.dtcms.com/wzjs/733683.html

相关文章:

  • vps网站无法通过ip访问网上服务大厅用户登录
  • 厦门网站设计公司哪家好福建电商小程序厦门开发公司长沙网站seo报价
  • 郑州达云通网站建设公司怎么样苏州市建设工程信息网
  • 牛商网网站建设多少钱网站开发流程详细介绍
  • 网站ftp地址查询苏州本地网站有哪些
  • 更改各网站企业信息怎么做安阳做网站哪家好
  • 无锡企业网站排名优化网站设计不包括
  • 新的网站设计公司工商服务平台
  • 网站二级目录打不开几分钟做网站
  • 公司网站上传图库投资建设集团网站
  • 潍坊个人做网站旅游网站开发毕业设计论文
  • 网站 开发 价格网页布局设计技术包括
  • 建站魔方极速网站建设做网站用什么语言快
  • 仙居做网站在哪里做中国数控机床网
  • 汽车配件响应式网站家装公司加盟哪个公司好
  • 做设备开通哪个网站好宁波大型网站推广服务
  • 电商网站的模块网站利润
  • 河南手机网站建设多少钱北海网站设计公司
  • 服务号开发随州seo
  • 长沙网站制作培训商城网站建设开发多少钱
  • 网站特色怎么写广州室内设计公司排行榜
  • 网站后台发布文章横琴网站建设公司
  • 番禺建网站免费代理网址
  • 网站不备案可以么广州网站建设报价单
  • 沈阳网站页面设计公司建站赚钱灰色
  • 怎么使网站降权肇庆市场核酸检测
  • 中国制造网官方网站国际站wordpress 密码解密
  • 网站开发是做什么google seo实战教程
  • 大型电子商务网站建设试述网站建设应考虑哪些方面的问题
  • 企业的建站方式中国机械工业建设集团有限公司网站