linux进程通信---消息队列

本文介绍了消息队列的基本概念及其实现方式,包括创建、发送、接收和控制消息队列等操作,并通过一个实例展示了两个进程如何利用消息队列进行通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

消息队列:消息队列是一些消息的列表,用户可以从消息队列中读取和添加消息,消息队列具有FIFO的特性,但可以实现消息的随机查询,比FIFO有更大的优势,这些消息都是存在于内核中,由“队列ID”来标识

消息队列的实现包括创建或打开消息队列,添加消息,读取消息,控制消息四种操作

创建或打开消息:使用msgget(),这里创建的消息队列的数量受到系统消息队列数量的限制

添加消息:使用msgsnd(),他把消息添加到消息队列的末尾

读取消息:使用msgrcv(),他把消息从消息队列中取走,与FIFO不同的是他可以取走某一条消息

控制消息:使用msgctl()控制消息队列,根据参数的不同可以完成多项功能

msgget()函数语法如下:

msgsnd()函数语法如下:

msgrcv()函数语法如下:

msgctl()函数语法如下:

这个例子说的两个进程通过消息队列进行通信:

发送端代码:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 512
struct message
{
    long msg_type ;//消息类型
    char msg_text[BUFFER_SIZE] ;//消息内容
};

int main()
{
    int qid ;
    key_t key ;
    struct message msg ;
    //ftok()函数根据路径和关键字生产标准的key
    if ((key = ftok(".", 'a')) == -1)
    {
        perror("ftok") ;
        exit(1) ;
    }
    //创建消息队列
    if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
    {
        perror("msgget") ;
        exit(1) ;
    }
    printf("open queue %d\n", qid) ;
    while(1)
    {
        printf("Enter some message to the queue:") ;
        if (fgets(msg.msg_text, BUFFER_SIZE, stdin) == NULL)
        {
            puts("no message") ;
            exit (1) ;
        }
        //将消息类型设置成进程的id
        msg.msg_type = getpid() ;
        //向消息队列中添加消息
        if (msgsnd(qid, &msg, strlen(msg.msg_text), 0) < 0)
        {
            perror("messaged posted") ;
            exit(1) ;
        }
        if (strncmp(msg.msg_text, "quit", 4) == 0)
        {
            break ;
        }
    }
    exit(0) ;
}

接收端:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 512
struct message
{
    long msg_type ;
    char msg_text[BUFFER_SIZE] ;
};
int main()
{
    int qid ;
    key_t key ;
    struct message msg ;
    if ((key = ftok(".", 'a')) == -1)
    {
        perror("ftok") ;
        exit(1) ;
    }
   if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
    {
        perror("msgset") ;
        exit(1) ;
    }
    printf("open queue%d\n", qid) ;
    do
    {
        memset(msg.msg_text, 0, BUFFER_SIZE) ;
        //从消息队列中获取消息
        if (msgrcv(qid, (void *)&msg, BUFFER_SIZE, 0, 0) < 0)
        {
            perror("msgrcv") ;
            exit(1) ;
        }
        printf("the message from process %d:%s", msg.msg_type, msg.msg_text) ;

    }while(strncmp(msg.msg_text, "quit", 4)) ;
    //删除消息队列
    if ((msgctl(qid, IPC_RMID, NULL)) < 0)
    {
        perror("msgctl") ;
        exit(1) ;
    }
    exit(0) ;
}
运行结果如下:

发送端:

接接收端:

由此可以看出两个进程使用id为65535的消息队列进行通信,消息队列内核自动实现了同步,所以不需要额外提供同步机制来自http://bbs.youkuaiyun.com/topics/300199658

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值