linux消息队列

消息队列的本质是消息的链表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。

接收进程可以独立地接收含有不同类型的数据结构。

目录

几个宏:

特点:

API:

例子:

执行:


几个宏:

MSGMAX   可发送是最长消息的长度                                2048

MSGMNB   特定队列的最大字节长度(亦即队列中所有消息之和)         4096

MSGMNI    系统中最大消息列数                                   50                   

MSGTOL    系统中最大消息数                                     50

特点:

  • 1,消息具有特定的格式和特定的优先级。
  • 2,独立于发送和接收进程。进程终止时,消息队列及其内容并不会删除。
  • 3,可以实现消息的随机查询,不一定是按先进先出读取,也可以按消息的类型读取。

API:

  • 1)msgget()创建和访问消息队列。

int msgget(key_t key, int flag);

  1. 如果没有与键值key相对应的消息队列,并且flag中包含了IPC_CREAT标志位。
  2. key参数为IPC_PRIVATE
  • 2)msgsend()把消息添加到消息队列。

int msgsnd(int msqid, const void *ptr, size_t size, int flag);

  1.  ptr是一个指向准备发送消息的指针,但是消息的数据结构有一定的要求,指针ptr所指向的消息结构一定要是一个长整型变量开始的结构体,接收成员将用这个成员来确定消息的类型。 long int message_type;
  2. size是ptr指向的消息的长度,该长度不包括长整型消息类型变量的长度。
  • 3)msgrcv()从一个消息队列获取消息。

int msgrcv(int msqid, void *ptr, size_t size,  long type, int flag);

  • 4)msgctl()控制消息队列。

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

  1.  其中 第三个参数 msqid_ds的结构体
struct msqid_ds
{
    uid_t shm_perm.uid;
    uid_t shm_perm.gid;
    mode_t shm_perm.mode;
};

例子:

msg_server.c

#include <uinstd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>

// 用于创建一个唯一的key
#define MSG_FILE "/etc/passwd"

// 消息结构
struct msg_form {
    long mtype;
    char mtext[256];
};

int main()
{
    int msqid;
    key_t key;
    struct msg_form msg;
    
    // 获取key值
    if((key = ftok(MSG_FILE,'z')) < 0)
    {
        perror("ftok error");
        exit(1);
    }

    // 打印key值
    printf("Message Queue - Server key is: %d.\n", key);

    // 创建消息队列
    if ((msqid = msgget(key, IPC_CREAT|0777)) == -1)
    {
        perror("msgget error");
        exit(1);
    }

    // 打印消息队列ID及进程ID
    printf("My msqid is: %d.\n", msqid);
    printf("My pid is: %d.\n", getpid());

    // 循环读取消息
    for(;;) 
    {
        msgrcv(msqid, &msg, 256, 888, 0);// 返回类型为888的第一个消息
        printf("Server: receive msg.mtext is: %s.\n", msg.mtext);
        printf("Server: receive msg.mtype is: %d.\n", msg.mtype);

        msg.mtype = 999; // 客户端接收的消息类型
        sprintf(msg.mtext, "hello, I'm server %d", getpid());
        msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
    }
    return 0;
}

msg_client.c

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/msg.h>

// 用于创建一个唯一的key
#define MSG_FILE "/etc/passwd"

// 消息结构
struct msg_form {
    long mtype;
    char mtext[256];
};

int main()
{
    int msqid;
    key_t key;
    struct msg_form msg;

    // 获取key值
    if ((key = ftok(MSG_FILE, 'z')) < 0) 
    {
        perror("ftok error");
        exit(1);
    }

    // 打印key值
    printf("Message Queue - Client key is: %d.\n", key);

    // 打开消息队列
    if ((msqid = msgget(key, IPC_CREAT|0777)) == -1) 
    {
        perror("msgget error");
        exit(1);
    }

    // 打印消息队列ID及进程ID
    printf("My msqid is: %d.\n", msqid);
    printf("My pid is: %d.\n", getpid());

    // 添加消息,类型为888
    msg.mtype = 888;
    sprintf(msg.mtext, "hello, I'm client %d", getpid());
    msgsnd(msqid, &msg, sizeof(msg.mtext), 0);

    // 读取类型为777的消息
    msgrcv(msqid, &msg, 256, 999, 0);
    printf("Client: receive msg.mtext is: %s.\n", msg.mtext);
    printf("Client: receive msg.mtype is: %d.\n", msg.mtype);
    return 0;
}

执行:

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值