linux下基于Posix message queue的同步消息队列的实现
/* 发送同步消息队列 */
_api int crtl_msgq_sync_send(crtl_mqd_t dst_mqd, const char *m_ptr, const size_t m_len, void *ack, size_t *ack_len, int timeout_sec, long timeout_nanosec)
{/* 入参有误 */if(unlikely(!m_ptr) || unlikely(!m_len) || unlikely(!ack) || unlikely(!ack_len)) {crtl_print_err("wrong params error.\n");crtl_assert_fp(stderr, 0);return CRTL_ERROR;}/* 为同步消息队列申请内存 */struct __crtl_msgq_sync_msg_body _unused *__msgq_sync_msg = crtl_malloc1(1, sizeof(struct __crtl_msgq_sync_msg_body)+m_len);if(unlikely(!__msgq_sync_msg)) {/* 申请失败,退出 */crtl_print_err("null pointer error.\n");crtl_assert_fp(stderr, 0);return CRTL_ERROR;}int _unused ret = CRTL_ERROR;crtl_msgq_name_t __ack_snd_mq_name;/* 消息队列名称 */sprintf(__ack_snd_mq_name, "%s", __CRTL_MSGQ_NAME_GEN("TMP", "ACK"));__crtl_dbg("MSGQ: %s\n", __ack_snd_mq_name);/* 创建消息队列 - 非阻塞-需要提供超时机制 */__msgq_sync_msg->__ack_snd_mqd = crtl_mq_open_nonblk(__ack_snd_mq_name, __CRTL_MSGQ_SYNC_TMP_MSGQ_MAXMSG, __CRTL_MSGQ_SYNC_TMP_MSGQ_MAXMSGSIZE);if(__msgq_sync_msg->__ack_snd_mqd == CRTL_ERROR) {/* 创建消息队列失败,释放内存,并退出 */crtl_print_err("Create tmp msgq error.\n");sleep(1);crtl_mfree1(__msgq_sync_msg);crtl_assert_fp(stderr, 0);return CRTL_ERROR;}__crtl_dbg("OPEN: mqd %d, \n", __msgq_sync_msg->__ack_snd_mqd);/* 创建临时消息队列成功,拷贝需要发送的数据 */__msgq_sync_msg->msg_size = m_len;memcpy(__msgq_sync_msg->msg_body, m_ptr, m_len);__crtl_dbg("SEND: mqd %d, \n", dst_mqd);/* 发送消息队列 */int ready_to_send_len = sizeof(struct __crtl_msgq_sync_msg_body)+m_len;int send_size = crtl_mq_send(dst_mqd, (char*)__msgq_sync_msg, ready_to_send_len, 10, 0,0,0);if(send_size < ready_to_send_len) {/* 如果失败,清空消息队列,删除文件,退出 */crtl_print_err("send size not equal, need %d, but is %d, error(mqd %d).\n", ready_to_send_len, send_size, dst_mqd);crtl_assert_fp(stderr, 0);crtl_mq_close(__msgq_sync_msg->__ack_snd_mqd);crtl_mq_unlink(__ack_snd_mq_name);crtl_mfree1(__msgq_sync_msg);return CRTL_ERROR;}__crtl_dbg("SEND: mqd %d, send_size %d , ready_to_send_len %d\n", dst_mqd, send_size, ready_to_send_len);/* 从临时消息队列接收消息(等待消息接收端调用 crtl_msgq_sync_send_ack ) */char __buf[__CRTL_MSGQ_SYNC_TMP_MSGQ_MAXMSGSIZE] = {0};unsigned int m_prio;int recv_ack_size = crtl_mq_receive(__msgq_sync_msg->__ack_snd_mqd, __buf, __CRTL_MSGQ_SYNC_TMP_MSGQ_MAXMSGSIZE, &m_prio, 1, timeout_sec, timeout_nanosec);if(recv_ack_size <= 0) {/* 如果接收失败或者超时,关闭临时消息队列,清空临时消息队列文件,释放内存 */crtl_print_err("recv ack error: recv %d error.\n", recv_ack_size);crtl_assert_fp(stderr, 0);crtl_mq_close(__msgq_sync_msg->__ack_snd_mqd);crtl_mq_unlink(__ack_snd_mq_name);crtl_mfree1(__msgq_sync_msg);return CRTL_ERROR;}__crtl_dbg("RECV ACK: mqd %d, ack_len %d\n", __msgq_sync_msg->__ack_snd_mqd, recv_ack_size);/* 如果从临时消息队列接收消息成功,向ack赋值, */*ack_len = recv_ack_size;memcpy(ack, __buf, recv_ack_size);__crtl_dbg("RECV ACK: mqd %d, ack_len %d\n", __msgq_sync_msg->__ack_snd_mqd, recv_ack_size);/* 整体流程结束,释放资源 */__crtl_dbg("MSGQ Close: %s\n", __ack_snd_mq_name);crtl_mq_close(__msgq_sync_msg->__ack_snd_mqd);crtl_mq_unlink(__ack_snd_mq_name);crtl_mfree1(__msgq_sync_msg);return send_size-sizeof(struct __crtl_msgq_sync_msg_body);
}/* 发送同步消息队列ack */
_api int crtl_msgq_sync_send_ack(const void *const src_sync_msg, const void *ack_msg, size_t ack_len)
{/* 入参有误 */if(unlikely(!src_sync_msg) || unlikely(!ack_msg) || unlikely(!ack_len)) {crtl_print_err("wrong params error.\n");crtl_assert_fp(stderr, 0);return CRTL_ERROR;}/* 解析同步消息中的msgq ID */struct __crtl_msgq_sync_msg_body *sync_msgq_msg = (struct __crtl_msgq_sync_msg_body *)src_sync_msg;crtl_mqd_t __tmp_mqd = sync_msgq_msg->__ack_snd_mqd;/* 向临时消息队列发送ACK消息 */int send_ack_size = crtl_mq_send(__tmp_mqd, (char*)ack_msg, ack_len, 0, 0,0,0);if(send_ack_size < ack_len) {crtl_print_err("send ack size not equal, need %d, but is %d, error.\n", ack_len, send_ack_size);crtl_assert_fp(stderr, 0);return CRTL_ERROR;}__crtl_dbg("MSGQ ACK SEND: mqd %d\n", __tmp_mqd);return send_ack_size;
}
linux下基于Posix message queue的同步消息队列的实现相关推荐
- MSMQ(MicroSoft Message Queue,微软消息队列)
MSMQ(MicroSoft Message Queue,微软消息队列)是在多个不同的应用之间实现相互通信的一种异步传输模式,相互通信的应用可以分布于同一台机器上,也可以分布于相连的网络空间中的任一位 ...
- Linux下Rsync+Inotify-tools实现数据实时同步
说明: 操作系统:CentOS 5.X 源服务器:192.168.21.129 目标服务器:192.168.21.127,192.168.21.128 目的:把源服务器上/home/www.osyun ...
- Linux下基于Libmad库的MP3音乐播放器编写
linux下基于Libmad库的MP3音乐播放器编写 libmad是一个开源mp3解码库,其对mp3解码算法做了很多优化,性能较好,很多播放器如mplayer.xmms等都是使用这个开源库进行解码的: ...
- linux c语言 信号,linux下基于C语言的信号编程实例
搜索热词 本文实例讲述了linux下基于C语言的信号编程方法.分享给大家供大家参考.具体如下: #include #include #include #include #include void si ...
- linux 多线程并行计算,Linux下使用POSIX Thread作多核多线程并行计算
POSIX线程库根据处理器.操作系统等特性封装了一台线程处理的接口.对于目前基于x86处理器架构的Linux系统来说,它往往会默认地将新创建的一个线程调度到与主线程不同的核中执行,如果这样能更好地平衡 ...
- Linux下Rsync+sersync实现数据实时同步
一.为什么要用Rsync+sersync架构? 1.sersync是基于Inotify开发的,类似于Inotify-tools的工具 2.sersync可以记录下被监听目录中发生变化的(包括增加.删除 ...
- Linux下基于ffmpeg音视频解码
Linux下基于ffmpeg音视频解码 1.ffmpeg简介 FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以 ...
- Linux下基于TCP的简易文件传输(socket编程)
Linux下基于TCP的简易文件传输(socket编程) OSI和TCP/IP: 关于TCP/IP协议 关于TCP协议 TCP编程的一般步骤[^2] TCP文件传输实现 功能概述 服务器编程 客户端编 ...
- Linux下基于密钥的安全验证实现方法
Linux下基于密钥的安全验证实现方法 -------OpenSSH+WinSCP+putty密钥生成器+putty 实验背景: 小诺公司目前已使用Linux搭建了各个服务器(FTP.DNS.Apac ...
最新文章
- android 界面长按,Android 主界面长按创建快捷方式
- 10.软件架构设计:大型网站技术架构与业务架构融合之道 --- 事务一致性
- 几种常见的Java排序算法
- android抓包为什么有些数据抓不了?抓包的辛酸历程
- css实现气泡框效果
- 流程:论文发表的流程
- 用OneDrive生成音乐外链和图片外链
- 使用Android Studio 查看内存泄漏
- 如何进入华为P40 debug 模式/开发者选项模式
- redis实现setnx,setex连用实现分布式锁
- 计算机管理没有指定运行,如何限制电脑只运行一个软件?只打开指定软件?
- token验证的方法
- 安装google输入法后,左shift键不能切换中英文
- android 三种常用的加密方式
- 自律·财大自习·Java
- python 使用 turtle 画双心(丘比特之箭)
- 民族企业夯实科技能力 助力数字经济高质量发展
- python实现教师工资调整程序
- Firefox ios 火狐浏览器iOS版本二次开发(二)
- JavaScript数据结构之哈希表
热门文章
- Java并发编程-ReadWriteLock读写锁
- 程序设计与算法----动态规划之最长公共子序列
- 小程序使用wxs 解决wxml保留2位小数问题
- 带宽检测工具iftop
- YUV422(UYVY)转RGB565源代码及其讲解.md
- DAG最长路问题 hdu-1224
- php输出文件,数组
- java list 在头部添加6_【Java提高十六】集合List接口详解
- mysql 监控工具安装_Mysql监控工具Innotop工具安装
- auto cad 打印颜色变浅_CAD制图软件中如何设置CAD打印样式表(CTB)?