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

Linux实用功能代码集(3) —— 线程间消息队列(1)

本文内容参考:

消息队列函数由msgget、msgctl、msgsnd、msgrcv四个函数解析_msgget函数-CSDN博客

特此致谢!

进程间通信机制中的消息队列很常见、经常会用到。主要是以下几个接口函数:

  • msgget函数

int msgget(key_t key, int msgflg);

得到消息队列标识符或创建一个消息队列对象。

  • msgctl函数

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

获取和设置消息队列的属性。

  • msgsnd函数

int msgsnd(int msqid, const void msgp, size_t msgsz, int msgflg);

将消息写入到消息队列。

  • msgrcv函数

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

从消息队列读取消息。

但是,线程之间的消息队列用的很少、或者说几乎没有用到过。那么同一进程的线程之间的消息队列(收发)机制应该如何实现呢?本文就来详细讲解一下。

有人可能会说了,同一进程的线程之间全局数据不是共享的么?怎么还需要消息队列?是这样,虽然线程之间数据是共享的,但也需要建立消息通信机制,一个线程阻塞或非阻塞接收数据,另一个线程发送数据(主要要找到那个“触发点”并同步)。

那么线程之间的消息队列具体应该是怎样实现的呢?通过什么来实现呢?这就引出了最主要的一个内容 —— 条件变量。可以说,条件变量是线程间的“通知器”。它主要涉及到两个函数:pthread_cond_init和pthread_cond_wait。

(1)pthread_cond_init函数

功能:

初始化条件变量(初始化通知器)。

原型:

#include <pthread.h> int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);

参数说明:

  • pthread_cond_t *cond:条件变量指针。
  • pthread_condattr_t *attr:属性(填NULL表示默认)。

常用写法:

pthread_cond_t cond; // 定义 pthread_cond_init(&cond, NULL); // 初始化 或 pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // 静态初始化

(2)pthread_cond_wait函数

功能:

让线程阻塞等待,直到被其它线程唤醒。

原型:

int pthread_cond_wait( pthread_cond_t *cond, pthread_mutex_t *mutex );

参数说明:

  • pthread_cond_t *cond:条件变量指针。
  • pthread_mutex_t *mutex:配合使用的互斥锁指针。

pthread_cond_wait函数内部做了3件事:

1)解锁mutex;

2)线程休眠(等通知);

3)被唤醒后,自动重新加锁 mutex。

典型用法的核心代码示例如下:

pthread_mutex_lock(&mutex); // 必须用 while 循环判断! while (没有消息) { pthread_cond_wait(&cond, &mutex); } // 处理消息... pthread_mutex_unlock(&mutex);

(3)pthread_cond_signal函数

功能:

唤醒一个正在pthread_cond_wait中休眠(等待)的线程。

原型:

#include <pthread.h> int pthread_cond_signal(pthread_cond_t *cond);

参数说明:

  • pthread_cond_t *cond:条件变量指针。

pthread_cond_signal函数内部做了以下事情:

1)检查有没有线程在pthread_cond_wait;

2)唤醒其中1个线程。

更为完整的用法示例代码如下:

// 全局变量 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int has_msg = 0; // 等待线程 void *wait_thread(void *arg) { pthread_mutex_lock(&mutex); // 等待消息 while (has_msg == 0) { printf("等待消息...\n"); pthread_cond_wait(&cond, &mutex); // 睡觉 } printf("收到消息!\n"); has_msg = 0; pthread_mutex_unlock(&mutex); return NULL; } // 唤醒线程 void *signal_thread(void *arg) { sleep(1); pthread_mutex_lock(&mutex); has_msg = 1; pthread_cond_signal(&cond); // 唤醒等待者 pthread_mutex_unlock(&mutex); return NULL; }

下一回给出实际代码并进行详细解析。

http://www.jsqmd.com/news/535317/

相关文章:

  • 北京回收宣纸|藏家急售无门路?丰宝斋上门回收,省心又靠谱 - 品牌排行榜单
  • Mermaid图表工具终极指南:三步学会专业图表零代码绘制
  • FPGA DSP48E2实战避坑:为什么你的32x32定点乘法性能上不去?从原理到优化全解析
  • 从N元文法到BERT:用Python代码串讲NLP核心模型演进(附实战代码)
  • 炫2张Nature主刊相关性热图
  • RadixAttention 技术详解:从原理到 SGLang 实践及 vLLM APC 对比
  • 2026年AI营销公司TOP5深度评估:从技术壁垒到实战效果的多维选型指南 - 小白条111
  • 惊艳效果展示:实时手机检测-通用镜像识别复杂场景手机案例
  • 接口频繁变化时,Flutter 项目如何保证稳定性?
  • NanoMsg vs ZeroMQ:轻量级通信库选型指南(性能对比+迁移成本分析)
  • 新手编程初体验:在快马用ai生成win11右键菜单还原win10的详细教程代码
  • 在职考公考编党必看!27公考备考APP性价比测评
  • 计算机毕业设计springboot社区物业管理系统 基于SpringBoot的智慧社区综合服务平台 基于SpringBoot的小区数字化运营管理系统
  • Windows Defender禁用技术深度解析:通过WSC API实现安全控制
  • ROS2 MoveIt配置实战:解决机械臂在RViz中‘只规划不执行’和模型不显示的常见问题
  • 嘉立创SMT加工避坑指南:如何用下单助手高效完成PCB焊接(附最新优惠信息)
  • LuaScript:Godot引擎Lua集成方案的轻量级脚本开发解决方案
  • DeepSeek-OCR镜像免配置方案:开箱即用的智能文档解析终端
  • Django Admin 后台让邮箱、科目必填 + 下拉选择
  • 如何让Flash内容重获新生?FlashPatch拯救过期浏览器插件的实战指南
  • 免费开源神器draw.io vs Processon:哪个更适合你的流程图需求?
  • 老旧设备焕新:OpenClaw在GTX1080上优化运行Qwen3-32B的技巧
  • ComfyUI-WanVideoWrapper终极指南:5步解锁高效AI视频生成
  • C语言弱符号与弱引用技术解析
  • P2469 [SDOI2010] 星际竞速 - Link
  • Hi3516CV610搭配PQStream图像采集全流程:Windows与Linux板端详细配置指南
  • 避坑指南:uniapp中使用echarts常见6大报错解决方案(2023最新版)
  • ESP32日志系统深度解析:如何灵活使用esp_log_level_set控制调试输出
  • so-vits-svc终极指南:如何免费实现高质量AI歌声转换
  • 开源工具Rufus实现专业级启动盘制作的完整指南