精通Unix下C语言编程与项目实践》之八 消息队列发送模型

简介:



《精通Unix下C语言编程与项目实践》之八

消息队列发送模型 
作者:朱云翔,胡平

12.4.2 消息队列发送模型

本处设计一个小例子描述发送消息的实际步骤,本例要求以阻塞方式向消息队列(关键字为KEY)中写入字符串“Hello Unix!”,消息类型为TYPE
全部过程共分为5个步骤:

1. 定义消息结构

参照代码12-4,定义以下消息结构:
struct msgbuf
{
    long    mtype;      /* 消息类型 */
    char    ctext[100]; /* 消息数据 */
};

2. 打开(创建)消息队列

int msgid;
msgid = msgget(KEY, 0666|IPC_CREAT);
if (msgid < 0) 打开(创建消息失败)
如果msgid值非负,表示打开(或创建)消息队列成功。

3. 组装消息

设置消息类型和拷贝消息数据:
struct msgbuf buf;                  /* 申请消息缓冲 */
buf.mtype = 100;                    /* 设置消息类型 */
strcpy(buf.ctext, "HELLO Unix!");   /* 拷贝消息数据 */

4. 发送消息

万事俱备,只欠东风,调用函数msgsnd完成消息发送:
int ret;
ret = msgsnd(msgid, &msg, strlen(msg.ctext), 0);
注意,参数msgsz只是消息数据的长度,不包含消息类型长度。

5. 发送判断

在计算机程序设计中,售后处理非常重要,如下所示:
if (ret == -1)
{
    if (errno == EINTR) 信号中断,重新发送;
    else 系统错误
}
进程在发送消息过程中如果接收到信号,将中止消息发送并返回EINTR错误,此时重新发送即可。

实例

本处设计一个消息发送的例子,它循环读取键盘输入,并将输入的字符串信息写入到消息队列(关键字为0x1234)中,如代码12-6所示:
代码12-6 消息发送程序(节自/code/chapter12/msg1.c
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <sys/errno.h>
extern int errno;
struct mymsgbuf             /* 定义消息结构 */
{
    long    mtype;          /* 消息类型 */
    char    ctext[100];     /* 消息数据 */
};
void main()
{
    struct mymsgbuf buf;    /* 申请消息缓冲 */
    int msgid;
    /* 打开(或创建)消息队列 */
    if ((msgid = msgget(0x1234, 0666|IPC_CREAT)) < 0)
    {
        fprintf(stderr, "open msg %X failed.\n", 0x1234);
        return ;
    }
    while (strncmp(buf.ctext, "exit", 4))
    {
        memset(&buf, 0, sizeof(buf));
        /* 从键盘输入消息数据内容 */
        fgets(buf.ctext, sizeof(buf.ctext), stdin);
        /* 设置消息类型为进程ID */
        buf.mtype = getpid();      
        /* 发送消息 */
        while ((msgsnd(msgid, &buf, strlen(buf.ctext), 0)) < 0)
        {
            if (errno == EINTR) continue;   /* 信号中断,重新发送 */
            return;
        }
    }
}
编译和运行代码12-6    
# make msg1
        cc -O -o msg1 msg1.c
# ./msg1
Please input:Hello World!
Please input:Hello Every Body!
Please input:读者朋友们,你们好!
Please input:exit
函数strncmp对字符串大小进行判断,当两个字符串参数完全相等时返回0,否则返回其它值。
程序调用fgets直接使用消息数据缓冲区存储输入,请确保输入字符串不要超过最大缓冲区限制,即本例中定义的99个字符(最后一个存储ASCII码的“0”)当用户输入exit时程序结束。上例中共发送了4条消息。
执行ipcs命令查询消息发送信息:
# ipcs -a -q
T     ID     KEY        MODE       OWNER    GROUP  CREATOR   CGROUP CBYTES  QNUM QBYTES LSPID LRPID  STIME    RTIME    CTIME
Message Queues:
q    162 0x00001234 --rw-rw-rw-     root      sys     root      sys     57     4  65532  1285     0 12:08:45 no-entry 12:08:28
如上所示,CBYTES值为57QNUM值为4,代表我们成功的写入了4条消息共57个字符信息。请确保执行程序msg1前消息队列0x1234不存在,或队列为空,否则显示的结果将不一致。



 本文转自 zhuyunxiang 51CTO博客,原文链接:http://blog.51cto.com/zhuyunxiang/135721,如需转载请自行联系原作者


相关文章
|
2月前
|
存储 算法 C语言
通义灵码在考研C语言和数据结构中的应用实践 1-5
通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
88 4
|
2月前
|
消息中间件 存储 Serverless
【实践】快速学会使用阿里云消息队列RabbitMQ版
云消息队列 RabbitMQ 版是一款基于高可用分布式存储架构实现的 AMQP 0-9-1协议的消息产品。云消息队列 RabbitMQ 版兼容开源 RabbitMQ 客户端,解决开源各种稳定性痛点(例如消息堆积、脑裂等问题),同时具备高并发、分布式、灵活扩缩容等云消息服务优势。
112 2
|
1天前
|
消息中间件 Java 开发工具
【实践】快速学会使用云消息队列RabbitMQ版
本次分享的主题是快速学会使用云消息队列RabbitMQ版的实践。内容包括:如何创建和配置RabbitMQ实例,如Vhost、Exchange、Queue等;如何通过阿里云控制台管理静态用户名密码和AccessKey;以及如何使用RabbitMQ开源客户端进行消息生产和消费测试。最后介绍了实验资源的回收步骤,确保资源合理利用。通过详细的操作指南,帮助用户快速上手并掌握RabbitMQ的使用方法。
30 10
|
15天前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
83 14
|
19天前
|
存储 编译器 C语言
【C语言】数据类型全解析:编程效率提升的秘诀
在C语言中,合理选择和使用数据类型是编程的关键。通过深入理解基本数据类型和派生数据类型,掌握类型限定符和扩展技巧,可以编写出高效、稳定、可维护的代码。无论是在普通应用还是嵌入式系统中,数据类型的合理使用都能显著提升程序的性能和可靠性。
40 8
|
23天前
|
C语言 开发者
C语言中的模块化编程思想,介绍了模块化编程的概念、实现方式及其优势,强调了合理划分模块、明确接口、保持独立性和内聚性的实践技巧
本文深入探讨了C语言中的模块化编程思想,介绍了模块化编程的概念、实现方式及其优势,强调了合理划分模块、明确接口、保持独立性和内聚性的实践技巧,并通过案例分析展示了其应用,展望了未来的发展趋势,旨在帮助读者提升程序质量和开发效率。
45 5
|
23天前
|
C语言
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性
C语言编程中,错误处理至关重要,能提升程序的健壮性和可靠性。本文探讨了C语言中的错误类型(如语法错误、运行时错误)、基本处理方法(如返回值、全局变量、自定义异常处理)、常见策略(如检查返回值、设置标志位、记录错误信息)及错误处理函数(如perror、strerror)。强调了不忽略错误、保持处理一致性及避免过度处理的重要性,并通过文件操作和网络编程实例展示了错误处理的应用。
56 4
|
23天前
|
存储 算法 C语言
用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容
本文探讨了用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容,旨在为开发者提供全面的指导和灵感。
37 2
|
1月前
|
C语言 Windows
C语言课设项目之2048游戏源码
C语言课设项目之2048游戏源码,可作为课程设计项目参考,代码有详细的注释,另外编译可运行文件也已经打包,windows电脑双击即可运行效果
32 1
|
2月前
|
消息中间件 安全 Java
云消息队列RabbitMQ实践解决方案评测
一文带你详细了解云消息队列RabbitMQ实践的解决方案优与劣
90 7
下一篇
DataWorks