这次主要写的是消息队列,之前讲过的管道和消息队列在本质上就有很大的区别,管道是一个文件,而消息队列是一个数据结构(类似于链表)。这说明了,管道文件是存放在磁盘上的,关机也会存在(尤其是命名管道更为显而易见,你不删除他他就搁那呆着),而消息队列是存在于内核中的内存,显而易见,关机就没了。
更关键的是,内存他快呀,比磁盘I/O快多了,为啥要用那么慢的管道。而且消息队列是可以直接完成没有亲缘关系的进程之间的通信的。但是结构比起管道要复杂,用到了很多结构体。内容有些多。先写一下和管道的主要区别,可以更直观的进行对比
- 匿名管道是跟随进程的,消息队列是跟随内核的,也就是说进程结束之后,匿名管道就死了,但是消息队列还会存在(除非显示调用函数销毁)
- 管道是文件,存放在磁盘上,访问速度慢,消息队列是数据结构,存放在内存,访问速度快
- 管道是数据流式存取,消息队列是数据块式存取
那么从头开始吧:
如何创建一个消息队列
在C库函数中有一个系统调用可以创建一个消息队列,那就是msgget,跟这个函数有关的其他函数也会一并给出来
- 函数原型: int msgget(key_t key, int msgflg)
- 头文件:#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>
- 参数解析
- 第一个参数是一个标识数据结构唯一的key键值,可以给IPC_PRIVATE让内核自动给,也可以自己调用ftok函数绑定一个
- 第二个参数是创建消息队列的参数,有IPC_CREAT 和 IPC_EXCL
- 单独使用IPC_CREAT,如果该消息队列已经存在(就是该key_t对象已经拿去被创建过一个队列了),打开该队列并返回,如果不存在,就创建一个返回
- 单独使用IPC_EXCL没有意义
- 两个参数一起使用(IPC_CREAT | IPC_EXCL),如果该队列存在,出错返回,如果不存在创建一个返回,也就是说这样使用一定会获得一个新队列
- 返回值,成功返回标志消息队列的唯一的一个int,失败返回-1
- 函数原型:key_t ftok(const char *pathname,int proj_id)
- 头文件:#include <sys/types.h> #include <sys/ipc.h>
- 参数解析
- 没啥好解析的,第一个参数就是给个路径(目录)就成了
- 第二个就是给个int值,没啥特殊要求,ftok本质就是把这个proj_id和pathname绑定在一起罢了
相关函数就这么多,到这里就可以开心的创建一个新的消息队列了,那么怎么看我们创建出来的消息队列呢?怎么销毁他呢?
先用命令看一下,使用ipcs -q就可查看消息队列的状态,这里我创建了一个消息队列,下面来销毁它
使用i