进程间通信——消息队列

来源:互联网 发布:mac客人用户退出不了 编辑:程序博客网 时间:2024/06/06 16:28
消息队列是一种临时存储消息的队列, 完成进程间数据传递, 优先级队列。

与信号量对比: 都以内核对象来确保多进程访问同一个消息队列, 信号量进行进程同步控制, 消息队列发送实际数据。

与管道对比: 管道发送的数据没有类型, 读取数据端无差别从管道中按照数据的前后顺序读取数据;消息队列数据有类型,读端可以根据数据类型读取特定数据。管道是一个文件;消息队列是一个数据结构(类似于链表)。管道文件是存放在磁盘上的,访问速度慢,关机也会存在;消息队列是存在于内核中的内存,访问速度快,关机就没了。无名管道是跟随进程的,消息队列是跟随内核的,也就是说进程结束之后,无名管道就死了,但是消息队列还会存在。管道是数据流式存取,消息队列是数据块式存取。

消息队列的创建或获取函数原型: int msgget(key_t key, int msgflg)参数解析 :key是一个标识数据结构唯一的key键值,可以IPC_PRIVATE让内核自动给,也可以自己调用ftok函数绑定一个。msgflg是创建消息队列的参数,有IPC_CREAT 和 IPC_EXCL 。单独使用IPC_CREAT,如果该消息队列已经存在,则打开该队列并返回,如果不存在,就新建一个返回。成功返回标志消息队列的唯一的一个int,失败返回-1。 消息队列的发送函数原型:int msgsnd(int msgid,const void *msgp,size_t msgsz,int msgflg)参数解析 :msgid是消息队列号。msgp是一个结构体的指针,这个结构体叫做msgbuf,这个是传输数据的数据块。msgsz是传输的消息长度。msgflg是传送方式的参数,没有可以设置为0。消息队列的获取函数原型:int msgrcv(int msgid,const void *msgp,size_t msgsz,long msgtyp,int msgflg)参数解析:msgid是消息队列号。msgp是一个结构体的指针,这个结构体叫做msgbuf,这个是传输数据的数据块。msgsz是传输的消息长度。msgtyp是用来表示当前进程拿数据的时候,只拿(msgbuf对象中的mtype)和传入的msgtyp一样的数据块(msgbuf对象)。msgflg是传送方式的参数,没有可以设置为0。成功返回长度,失败返回-1。消息队列的销毁函数原型: int msgctl(int msgid ,int cmd ,struct msgid_ds *buf)参数解析:msgid是创建好的标识msg的int变量cmd设置为IPC_RMID。*buf设置为0。

进程B接收并打印进程A的数据

A

#include <stdio.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <assert.h>#include <sys/msg.h>#include <sys/types.h>#include <sys/ipc.h>struct msgbuff{    long type;    char  data[128];};void main(){    int msgid = msgget((key_t)1234, IPC_CREAT | 0664);    assert(msgid != -1);    struct msgbuff  buff;    buff.type = 1000;    strcpy(buff.data, "hello");    msgsnd(msgid, &buff, strlen(buff.data), 0);    buff.type = 2000;    strcpy(buff.data, "world");    msgsnd(msgid, &buff, strlen(buff.data), 0);}

B

#include <stdio.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <assert.h>#include <sys/msg.h>#include <sys/types.h>#include <sys/ipc.h>struct msgbuff{    long type;    char  data[128];};void main(){    int msgid = msgget((key_t)1234, IPC_CREAT | 0664);    assert(msgid != -1);    struct msgbuff buff;    memset(&buff, 0, sizeof(buff));    msgrcv(msgid, &buff, 127, 1000, 0);    printf("%s\n", buff.data);}
原创粉丝点击