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

用 C 实现一个简化版 MessageQueue

Android 的 MessageQueue 很复杂(native poll/epoll、barrier、idle handler…)
但它的核心思想非常简单
✅ 一个队列存消息
✅ 一个循环不断取消息执行
✅ 线程安全(加锁/条件变量)

我们用 C 写一个可跑的简化版

  • 支持post(msg)

  • 支持loop()阻塞取消息

  • 支持quit()退出

1)数据结构:消息节点 + 队列

typedef struct Message { int what; void (*callback)(int what); // 收到消息后执行的回调 struct Message* next; } Message; typedef struct { Message* head; Message* tail; int quit; pthread_mutex_t mutex; pthread_cond_t cond; } MessageQueue;

2)队列初始化 / 销毁

void mq_init(MessageQueue* q){ q->head = q->tail = NULL; q->quit = 0; pthread_mutex_init(&q->mutex, NULL); pthread_cond_init(&q->cond, NULL); } void mq_destroy(MessageQueue* q){ pthread_mutex_lock(&q->mutex); Message* cur = q->head; while(cur){ Message* next = cur->next; free(cur); cur = next; } q->head = q->tail = NULL; pthread_mutex_unlock(&q->mutex); pthread_mutex_destroy(&q->mutex); pthread_cond_destroy(&q->cond); }

3)post:入队 + 唤醒 loop

void mq_post(MessageQueue* q, int what, void (*cb)(int)){ Message* m = (Message*)malloc(sizeof(Message)); m->what = what; m->callback = cb; m->next = NULL; pthread_mutex_lock(&q->mutex); if(q->tail == NULL){ q->head = q->tail = m; }else{ q->tail->next = m; q->tail = m; } pthread_cond_signal(&q->cond); // 通知消费者 pthread_mutex_unlock(&q->mutex); }

4)next:阻塞取消息(队列空就等)

Message* mq_next(MessageQueue* q){ pthread_mutex_lock(&q->mutex); while(!q->quit && q->head == NULL){ pthread_cond_wait(&q->cond, &q->mutex); } if(q->quit){ pthread_mutex_unlock(&q->mutex); return NULL; } Message* m = q->head; q->head = m->next; if(q->head == NULL) q->tail = NULL; pthread_mutex_unlock(&q->mutex); return m; }

5)loop:像 Looper 一样执行消息

void mq_loop(MessageQueue* q){ while(1){ Message* m = mq_next(q); if(m == NULL) break; if(m->callback){ m->callback(m->what); } free(m); } }

6)quit:让 loop 退出

void mq_quit(MessageQueue* q){ pthread_mutex_lock(&q->mutex); q->quit = 1; pthread_cond_broadcast(&q->cond); pthread_mutex_unlock(&q->mutex); }

7)完整可运行 Demo(Linux / macOS)

编译:gcc mq.c -o mq -lpthread

#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> typedef struct Message { int what; void (*callback)(int what); struct Message* next; } Message; typedef struct { Message* head; Message* tail; int quit; pthread_mutex_t mutex; pthread_cond_t cond; } MessageQueue; void mq_init(MessageQueue* q){ q->head = q->tail = NULL; q->quit = 0; pthread_mutex_init(&q->mutex, NULL); pthread_cond_init(&q->cond, NULL); } void mq_post(MessageQueue* q, int what, void (*cb)(int)){ Message* m = (Message*)malloc(sizeof(Message)); m->what = what; m->callback = cb; m->next = NULL; pthread_mutex_lock(&q->mutex); if(q->tail == NULL){ q->head = q->tail = m; }else{ q->tail->next = m; q->tail = m; } pthread_cond_signal(&q->cond); pthread_mutex_unlock(&q->mutex); } Message* mq_next(MessageQueue* q){ pthread_mutex_lock(&q->mutex); while(!q->quit && q->head == NULL){ pthread_cond_wait(&q->cond, &q->mutex); } if(q->quit){ pthread_mutex_unlock(&q->mutex); return NULL; } Message* m = q->head; q->head = m->next; if(q->head == NULL) q->tail = NULL; pthread_mutex_unlock(&q->mutex); return m; } void mq_quit(MessageQueue* q){ pthread_mutex_lock(&q->mutex); q->quit = 1; pthread_cond_broadcast(&q->cond); pthread_mutex_unlock(&q->mutex); } void mq_loop(MessageQueue* q){ while(1){ Message* m = mq_next(q); if(m == NULL) break; if(m->callback) m->callback(m->what); free(m); } } void mq_destroy(MessageQueue* q){ pthread_mutex_lock(&q->mutex); Message* cur = q->head; while(cur){ Message* next = cur->next; free(cur); cur = next; } q->head = q->tail = NULL; pthread_mutex_unlock(&q->mutex); pthread_mutex_destroy(&q->mutex); pthread_cond_destroy(&q->cond); } void on_msg(int what){ printf("handle msg what=%d (thread=%lu)\n", what, (unsigned long)pthread_self()); } typedef struct { MessageQueue* q; } ProducerArg; void* producer(void* arg){ ProducerArg* pa = (ProducerArg*)arg; for(int i=1;i<=5;i++){ mq_post(pa->q, i, on_msg); usleep(200 * 1000); } mq_quit(pa->q); return NULL; } int main(){ MessageQueue q; mq_init(&q); pthread_t t; ProducerArg pa = { .q = &q }; pthread_create(&t, NULL, producer, &pa); mq_loop(&q); pthread_join(t, NULL); mq_destroy(&q); return 0; }

8)这跟 Android MessageQueue 的对应关系

  • mq_postenqueueMessage
  • mq_nextnext()
  • mq_loopLooper.loop()
  • cond_wait≈ “没有消息就阻塞等待”
  • quitLooper.quit()
http://www.cnnetsun.cn/news/66205.html

相关文章:

  • 缓存与数据库一致性解决方案深度解析
  • 消息队列真仙:我的道念支持最终一致性
  • Spring Boot项目推送Gitee全流程(进阶)
  • Java毕设项目:基于Springboot大学校园自习室教室座位预约网站设计与实现基于springboot高校自习室预约系统的设计与实现(源码+文档,讲解、调试运行,定制等)
  • JAVA打造同城羽馆预约,一键畅享运动
  • 经验贴 | 科学制定招聘需求与预算:HR 必看的逻辑与实操要点
  • 经验贴 | AI 面试评估系统怎么用?HR 高效识人实操指南
  • 构建个性化AI助手:LobeChat会话管理功能深度使用技巧
  • 基于昇腾NPU的YOLOV8-seg c++部署
  • 26、深入探索脚本编程与系统安全基础
  • XSS漏洞有哪几种?DOM型XSS和反射型有什么区别?SQL注入原理又是什么?网安面试题常见问题一文详解
  • 压力扫描阀:并行校准技术,解锁多点压力测量新高度
  • PyTorch框架下运行Qwen3-32B的内存优化策略
  • 为什么说Qwen3-8B是学术研究的理想选择?实测报告出炉
  • java基础-PriorityQueue(优先队列)
  • Qwen3-14B模型量化压缩技术:降低GPU内存占用
  • 18、日期和时间的格式化、解析及时间区域的使用
  • VisionPro CogIPOneImageTool1 工具超详细解释(含内部功能全解析)
  • VisionPro CogIDTool 工具超深度详解(技术细节 + 实战配置版)
  • 让 BI 拥有‘领域大脑’:智能 BI 如何实现 AI 级精准数据查询
  • 提示工程架构师的战略规划:提示系统生命周期管理
  • 条形码识别与定位:基于FCOS框架的多类型条码检测与识别技术详解
  • AutoGPT能否用于学术文献综述?研究辅助工具测评
  • 如何用AutoGPT实现任务全自动执行?深度解析开源大模型能力
  • Mapbox GL JS 核心表达式:`in` 包含判断完全教程
  • Web3双核引擎:当AI量化金融大脑,遇见DAO社交生态灵魂
  • CEX开发困局:当达普韦伯为交易所注入“数字灵魂”
  • AutoGPT镜像集成指南:如何嵌入现有业务系统?
  • AutoGPT项目活跃度分析:GitHub星标增长趋势
  • AutoGPT能否生成短视频脚本?内容创作新方式