IPC-消息队列

来源:互联网 发布:淘宝怎样买枪 编辑:程序博客网 时间:2024/04/30 15:33

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
原创粉丝点击