进程通讯
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