IPC-消息队列

IPC-消息队列


父子进程之间

#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<string.h>

struct msgbuf
{
    long mtype;
    char mdata[1024];
};

int main(void)
{
    int msgid = msgget(IPC_PRIVATE, 0666|IPC_CREAT);
    if(-1 == msgid)
    {
        perror("msgget");
        exit(EXIT_FAILURE);
    }
    struct msgbuf msg;
    memset(&msg, 0, sizeof(struct msgbuf));
    if(fork() > 0)
    {
        msg.mtype = 1;
        strcpy(msg.mdata, "Hello world");
        if(-1 == msgsnd(msgid, &msg, sizeof(struct msgbuf), 0))
        {
            perror("msgsnd");
            exit(EXIT_FAILURE);
        }
        wait(NULL);
        msgctl(msgid, IPC_RMID, NULL);
        return 0;
    }
    sleep(1);
    if(-1 == msgrcv(msgid, &msg, sizeof(struct msgbuf), 1, 0))  // 在消息队列中接收类型为1的消息
    {
        perror("msgrcv");
        exit(EXIT_FAILURE);
    }
    printf("child process receive: %s\n", msg.mdata);
    return 0;
}

非亲缘关系进程之间

process.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>

struct msgbuf
{
    long mtype;
    char data[1024];
};

int main(void)
{
    key_t key = ftok("process.c", 'a');
    if(-1 == key)
    {
        perror("ftok");
        exit(EXIT_FAILURE);
    }
    int msgid = msgget(key, 0666|IPC_CREAT);
    if(-1 == msgid)
    {
        perror("msgget");
        exit(EXIT_FAILURE);
    }
    struct msgbuf msg;
    memset(&msg, 0, sizeof(struct msgbuf));
    msg.mtype = 1;
    strcpy(msg.data, "Hello world");
    if(-1 == msgsnd(msgid, &msg, sizeof(struct msgbuf), 0))
    {
        perror("msgsnd");
        exit(EXIT_FAILURE);
    }
    memset(&msg, 0, sizeof(struct msgbuf));
    if(-1 == msgrcv(msgid, &msg, sizeof(struct msgbuf), 2, 0))
    {
        perror("msgrcv");
        exit(EXIT_FAILURE);
    }
    printf("Receive from 2 : %s\n", msg.data);

    sleep(1);   // 等待process2读取消息队列,再删除消息队列
    if(-1 == msgctl(msgid, IPC_RMID, NULL))
    {
        perror("msgctl");
        exit(EXIT_FAILURE);
    }
    return 0;
}

process2.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<sys/types.h>

struct msgbuf
{
    long mtype;
    char data[1024];
};

int main(void)
{
    key_t key = ftok("process.c", 'a');
    if(-1 == key)
    {
        perror("ftok");
        exit(EXIT_FAILURE);
    }
    int msgid = msgget(key, 0666|IPC_CREAT);
    if(-1 == msgid)
    {
        perror("msgget");
        exit(EXIT_FAILURE);
    }
    struct msgbuf msg;
    memset(&msg, 0, sizeof(struct msgbuf));
    msg.mtype = 2;
    strcpy(msg.data, "How are you");
    if(-1 == msgsnd(msgid, &msg, sizeof(struct msgbuf), 0))
    {
        perror("msgsnd");
        exit(EXIT_FAILURE);
    }
    memset(&msg, 0, sizeof(struct msgbuf));
    if(-1 == msgrcv(msgid, &msg, sizeof(struct msgbuf), 1, 0))
    {
        perror("msgrcv");
        exit(EXIT_FAILURE);
    }
    printf("Receive from 1 : %s\n", msg.data);
    return 0;
}

管道消息队列的比较

  • 相同之处:
    通过与命名管道一样,消息队列进行通信的进程可以是不相关的进程,同时它们都是通过发送和接收的方式来传递数据的。在命名管道中,发送数据用write,接收数据用read,则在消息队列中,发送数据用msgsnd,接收数据用msgrcv。而且它们对每个数据都有一个最大长度的限制。

  • 与命名管道相比,消息队列的优势在于:
    1、消息队列也可以独立于发送和接收进程而存在,从而消除了在同步命名管道的打开和关闭时可能产生的困难。
    2、同时通过发送消息还可以避免命名管道的同步和阻塞问题,不需要由进程自己来提供同步方法。
    3、接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值