进程间通讯(七)消息队列

匿名 (未验证) 提交于 2019-12-02 23:37:01

进程通讯

linux文件描述符表、文件表、索引节点表的关系
进程间通讯(一)基本概念
进程间通讯(二)无名管道
进程间通讯(三)有名管道
进程间通讯(四)popen和pclose
进程间通讯(五)信号
进程间通讯(六)共享内存
进程间通讯(七)消息队列

消息队列

消息队列时通过链表,将一个一个的消息构成了一个队列,存储在内核空间中,每个消息都有自己的类型

每一个消息队列都有一个msqid_ds结构体与之关联,msqid_ds结构体标记着消息队列的状态,还有消息队列的链表头和链表尾

可以使用下面结构体来表示消息

struct msg {     long type;     int len;     char buf[n]; }; 

消息队列相关API介绍

函数形式:int msgget(key_t key, int flag) 功能:获取或者创建一个消息队列 参数:key - 和消息队列关联的key值,key可以设置为IPC_PRIVATE(只能在父子进程通讯),也可以是ftok创建 参数:flag - 消息队列的访问权限 返回值:成功是消息队列ID,出错是-1 
函数形式:int msgsnd(int msqid, const void *msgp, size_t size, int flag) 功能:发送消息 参数:msqid - 消息队列的ID 参数:msgp - 指向消息的指针(消息的结果体如上struct msg) 参数:size - 发送的消息正文的字节数 参数:flag - IPC_NOWAIT(非阻塞) 0(阻塞) 返回值:成功是0,出错是-1 
函数形式:int msgrcv(int msgid, void* msgp, size_t size, long msgtype, int flag) 功能:接受消息 参数:msqid - 消息队列的ID 参数:msgp - 要接收的消息的字节数 参数:msgtype - 0(返回消息列表的第一个消息) 大于0(接收第一个类型为msgtyp的消息) 小于0(小于msgtype绝对值又最小的消息) 参数:flag - IPC_NOWAIT(非阻塞) 0(阻塞) 返回值:成功是消息长度,出错是-1 
函数形式:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf) 功能:接受消息 参数:msqid - 消息队列的ID 参数:cmd - IPC_STAT(读取消息队列的属性); IPC_SET(设置消息队列的属性); IPC_RMID(删除消息队列) 参数:flag - IPC_NOWAIT(非阻塞) 0(阻塞) 返回值:成功是0,出错是-1	

下面的例子使用消息队列实现进程间通讯

#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>  struct msg {     long type;     int len;     char buf[1024]; };  int msgrm(int msqid) {     return msgctl(msqid, IPC_RMID, NULL); }  int main(int argc, char *argv[]) {     pid_t pid;      pid = fork();     if(pid < 0)         return -1;     else if(pid == 0)     {         key_t key = ftok("test.txt", 1);         int msqid = msgget(key, 0666|IPC_CREAT);         if(msqid == -1)             return -1;          struct msg msg;         while(1)         {             msgrcv(msqid, &msg, sizeof(msg), 1, 0);             printf("child: msg len(%d)\n", msg.len);             printf("child: msg(%s)\n", msg.buf);              msg.type = 2;             strcpy(msg.buf, "Hello, I am child.");             msg.len = strlen(msg.buf);             msgsnd(msqid, &msg, sizeof(msg), 0);             sleep(1);         }     }      while(1)     {         key_t key = ftok("test.txt", 1);         int msqid = msgget(key, 0666|IPC_CREAT);         if(msqid == -1)             return -1;          struct msg msg;         while(1)         {             msg.type = 1;             strcpy(msg.buf, "Hello, I am parent.");             msg.len = strlen(msg.buf);             msgsnd(msqid, &msg, sizeof(msg), 0);             sleep(1);              msgrcv(msqid, &msg, sizeof(msg), 2, 0);             printf("parent: msg len(%d)\n", msg.len);             printf("parent: msg(%s)\n", msg.buf);                 }     }      return 0; } 
文章来源: https://blog.csdn.net/weixin_42462202/article/details/90751715
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!