消息队列
消息队列是消息的链表,存放在内存中,由内核维护
IPC对象
除了最原始的进程间通信方式,信号,无名管道,有名管道外,还有三种进程间通信方式称之为IPC对象
IPC 对象的分类; 消息队列,共享内存,信号灯集
IPC对象也是在内核空间开辟区域,每一种IPC对象创建好之后,都会将其设置为全局,并且会给其分配一个编号,只要找到唯一的这个编号,就可以进行通信,所以不相关的进程,也可以通过IPC对象进行通信
IPC对象创建好之后,会在当前系统中可见,只要不删除或者不关闭系统,就会一直存在
查看已经创建的IPC对象
ipcs 查看当前系统中所有创建的IPC对象
ipcs -q 查看创建的消息队列
ipcs - m 查看创建的共享内存
ipcs -s 查看信号量
ipcrm 删除IPC对象
例如:ipcrm -q msqid 删除标号为msqid的消息队列
消息队列概述
消息队列是消息的链表,存放在内存中,由内核维护
消息队列的特点
1、消息队列中的消息是有类型的。
2、消息队列中的消息是有格式的。
3、消息队列可以实现消息的随机查询。消息不一定要以先进先出的次序读取,编程时可以按消息的类型读取。
4、消息队列允许一个或多个进程向它写入或者读取消息。
5、与无名管道、命名管道一样,从消息队列中读出消息,消息队列中对应的数据都会被删除。
6、每个消息队列都有消息队列标识符,消息队列的标识符在整个系统中是唯一的。
7、只有内核重启或人工删除消息队列时,该消息队列才会被删除。若不人工删除消息队列,消息队列会一直存在于系统中。
System V提供的IPC通信机制需要一个key值,通过key值就可在系统内获得一个唯一的消息队列标识符,key值可以是人为指定的,也可以通过ftok函数获得
如果多个进程想通过IPC对象通信,则必须找到唯一的标识,而唯一的标识是由key值决定的,所以只要key值知道,则就可以实现多个进程通信
ftok函数
#include <sys/types.h>
#include <sys/ipc.h>
功能
通过文件名和目标值共同创造一个键值并返回值
参数
pathname:任意一个文件名(文件名或者目录名)
proj_id: 目标值,范围一般0 ~ 127
返回值
成功返回key值,失败返回-1
如果使用frok函数获取键值,得到的键值是由ftok的第一个参数对应文件的信息,和第二个参数一起决定的
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
int main()
{
//使用ftok函数获取key值
//只要保证ftok的第一个参数对应的文件和第二个参数值相同
//则不管程序运行多少遍或者多少个进程获取键值,键值一定都是唯一的
key_t mykey;
if((mykey = ftok(".", 100 )) == -1)
{
perror("fail to ftok");
exit(1);
}
printf("key = %#x\n", mykey);
//以16进制方式打印 #是为了得到 0x
return 0;
}
消息队列的操作
创建消息队列
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
功能
创建一个新的或打开一个已经存在的消息队列,不同的进程调用此函数,只要用相同的key值就能得到同一个消息队列的标识符
参数
key: IPC键值
获取键值,方法1:随便指定一个数,方法2,使用ftok函数获取键值
msgflg:标识函数的行为及消息队列的权限
IPC_CREAT: 创建消息队列
IPC_EXCL:检测消息队列是否存在
位或权限位:消息队列位或权限位后可以设置消息队列的访问权限,格式和open函数的mode_t一样,但可执行权限未使用
msgflg: 消息队列的访问权限,一般设置为IPC_CREAT | IPC_EXCL | 0777 |或者
IPC_CREAT | 0666(这个方法用的多点)
返回值:
成功:消息队列的id,失败:返回-1
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
int main()
{
int msqid
//通过ftok函数获取ipc的值
key_t mykey;
if(( mykey = ftok(".", 100)