IPC----消息队列
消息队列可以认为是一个消息链表,System V 消息队列使用消息队列标识符标识。具有足够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息。在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达。System V 消息队列是随内核持续的,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。可以将内核中的某个特定的消息队列画为一个消息链表,如下图所示:
对于系统中每个消息队列,内核维护一个msqid_ds的信息结构:
struct msqid_ds {
struct ipc_perm msg_perm;
struct msg *msg_first; /* first message on queue,unused */
struct msg *msg_last; /* last message in queue,unused */
__kernel_time_t msg_stime; /* last msgsnd time */
__kernel_time_t msg_rtime; /* last msgrcv time */
__kernel_time_t msg_ctime; /* last change time */
unsigned long msg_lcbytes; /* Reuse junk fields for 32 bit */
unsigned long msg_lqbytes; /* ditto */
unsigned short msg_cbytes; /* current number of bytes on queue */
unsigned short msg_qnum; /* number of messages in queue */
unsigned short msg_qbytes; /* max number of bytes on queue */
__kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */
__kernel_ipc_pid_t msg_lrpid; /* last receive pid */
};
1.消息队列允许进程以消息的形式交换数据。读写都是针对整条消息,不能读写消息的一部分,不像管道那样可以以流的形式读写任意字节。
2.消息队列除了包含数据外,还有一个整数来表示该消息的类型。读取消息的时候即可以按照先进先出方式读取,也可以按照消息类型来读取。
接口函数
1.创建一个消息队列
#include <sys/msg.h>
#include <sys/types.h>
#include <sys/ipc.h> int msgget(key_t key, int msgflg);
key:是一个整数,该函数会将key转换成一个IPC标识符。
key有3种方法定义:
1)手动随意指定一个整数。
2)把IPC_PRIVATE当作key传入,系统会自动生成。
3)用ftok()函数。
注:参数key设置成常数IPC_PRIVATE并不意味着其他进程不能访问该消息队列,只意味着即将创建新的消息队列。
参数msgflg可以为以下:IPC_CREAT、IPC_EXCL、IPC_NOWAIT或三者的或结果。
调用返回:成功返回消息队列描述字,否则返回-1。
在以下两种情况下,该调用将创建一个新的消息队列:
- 如果没有消息队列与健值key相对应,并且msgflg中包含了IPC_CREAT标志位;
- key参数为IPC_PRIVATE;
2.发送消息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h> int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msqid:用msget()获取的id。
mgsp:存储消息的结构指针,下面的mtype就是自定义的消息类型,mtext是消息数据。
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
对发送消息来说,有意义的msgflg标志为IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息时,msgsnd是否等待。造成msgsnd()等待的条件有两种:
- 当前消息的大小与当前消息队列中的字节数之和超过了消息队列的总容量;
- 当前消息队列的消息数(单位"个")不小于消息队列的总容量(单位"字节数"),此时,虽然消息队列中的消息数目很多,但基本上都只有一个字节。
msgsnd()解除阻塞的条件有三个:
1)不满足上述两个条件,即消息队列中有容纳该消息的空间;
2)msqid代表的消息队列被删除;
3)调用msgsnd()的进程被信号中断;
调用返回:成功返回0,否则返回-1。
功能: 该系统调用从msgid代表的消息队列中读取一个消息,并把消息存储在msgp指向的msgbuf结构中。
msgsnd()解除阻塞的条件有三个:
- 不满足上述两个条件,即消息队列中有容纳该消息的空间;
- msqid代表的消息队列被删除;
- 调用msgsnd()的进程被信号中断;
3.接收消息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h> ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
msqid为消息队列描述字;
消息返回后存储在msgp指向的地址;
msgsz指定msgbuf的mtext成员的长度(即消息内容的长度);
msgtyp为请求读取的消息类型;即msgbuf里面的mtype。但还有别的用法:
如果为0,就获取队列中第一个可用消息。
大于0,获取相同类型消息的第一个,即mtype。
小于0,获取等于或小于mtype的绝对值的所有消息中最小的一个。
读消息标志msgflg可以为以下几个常值的或:
- IPC_NOWAIT 如果没有满足条件的消息,调用立即返回,此时,errno=ENOMSG
- IPC_EXCEPT 与msgtyp>0配合使用,返回队列中第一个类型不为msgtyp的消息
- IPC_NOERROR 如果队列中满足条件的消息内容大于所请求的msgsz字节,则把该消息截断,截断部分将丢失。
调用返回:成功返回读出消息的实际字节数,否则返回-1。
功能: 该系统调用从msgid代表的消息队列中读取一个消息,并把消息存储在msgp指向的msgbuf结构中。
msgrcv()解除阻塞的条件有三个:
- 消息队列中有了满足条件的消息;
- msqid代表的消息队列被删除;
- 调用msgrcv()的进程被信号中断;
4.消息控制
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buf);
cmd:有3个选项,IPC_STAT,IPC_SET,IPC_RMID。
- IPC_STAT:该命令用来获取消息队列信息,返回的信息存贮在buf指向的msqid_ds结构中;
- IPC_SET:该命令用来设置消息队列的属性,要设置的属性存储在buf指向的msqid结构中;可设置属性包括:msg_perm.uid、msg_perm.gid、msg_perm.mode以及msg_qbytes,同时,也影响msg_ctime成员。
- IPC_RMID:删除msqid标识的消息队列;
调用返回:成功返回0,否则返回-1。
例子程序见参考3
参考:
System V进程间通信—— 消息队列 http://blog.chinaunix.net/uid-22566367-id-1727281.html
System V IPC(1)-消息队列 http://www.cnblogs.com/yuuyuu/p/5133915.html
System V 消息队列 http://www.cnblogs.com/Anker/archive/2013/01/07/2848869.html
IPC----消息队列的更多相关文章
- IPC——消息队列
Linux进程间通信——使用消息队列 下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信——使用命名管 ...
- linux IPC 消息队列(二)
我在网上想找多进程之间的通信方式,发现有人写的消息队列很好,搬过来: common.h #ifndef __COMMON_H_ #define __COMMON_H_ #include <std ...
- linux IPC 消息队列
消息队列函数原型 在建立IPC通讯时(如消息队列,共享内存)必须建立一个ID值.通常情况下,这个ID值由ftok函数得到 #inlcude <sys/types.h> #include & ...
- 进程间通信IPC:消息队列,信号量,共享内存
2015.3.4星期三 阴天 进程间通信:IPC 文件对象:记录文件描述符,文件开关等 IPC标示符:系统全局的流水号两个进程要通信,打开的是唯一的对象进行通讯,通过key操作 XSI IPC:消息队 ...
- System V IPC 之消息队列
消息队列和共享内存.信号量一样,同属 System V IPC 通信机制.消息队列是一系列连续排列的消息,保存在内核中,通过消息队列的引用标识符来访问.使用消息队列的好处是对每个消息指定了特定消息类型 ...
- 进程(守护进程--互斥锁--IPC机制--生产者模型--僵尸进程与孤儿进程--模拟抢票--消息队列)
目录 一:进程理论知识 1.理论知识 二:什么是进程? 三:僵尸进程与孤儿进程 1.僵尸进程 四:守护进程 1.什么是守护进程? 2.主进程创建守护进程 3.守护进程 五:互斥锁(模拟多人抢票) 1. ...
- 【windows 操作系统】进程间通信(IPC)简述|无名管道和命名管道 消息队列、信号量、共享存储、Socket、Streams等
一.进程间通信简述 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进 ...
- linux下的进程间通信之消息队列
概念: 进程彼此之间可以通过IPC消息进行通信.进程产生的每条消息都被发送到一个IPC消息队列中,这条消息一直存放在队列中,直到另一个进程将其读走为止. 优点:可以通过发送消息来几乎完全避免命名管道的 ...
- Linux IPC System V 消息队列
模型 #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> ftok() //获取key ...
- System V IPC(1)-消息队列
一.概述 System V三种IPC:消息队列,信号量,共享内存.这三种IPC最先出现在AT&am ...
随机推荐
- MySQL索引之前缀索引和索引选择性
有时需要索引很长的字符列,它会使索引变大而且变慢.一个策略就是模拟哈希索引.但是有时这也不够好,那? 通常可以索引开始的几个字符,而不是全部值,以节约空间并得到好的性能.这使索引需要的空间变小,但是也 ...
- 新浪微博客户端(40)-使用AFN发送带图片的微博
DJComposeViewController.m /** 发微博 */ - (void)sendStatusRequest { AFHTTPSessionManager *RequestManage ...
- JMS基本概念和模型
------------------------------------------------------------------------------------------- JMS是什么 J ...
- 关于高性能Web服务的一点思考
下面这些概念对于专业做性能测试的会比较熟悉,但是对于开发人员不一定都那么清楚. 并发用户数: 某一时刻同时请求服务器的用户总数,通常我们也称并发数,并发连接数等. 吞吐率:对于web服务器来说就是每秒 ...
- 第三天 moyax
struct Blog { static let BaseURL = NSURL(string: "http://192.168.1.103/blog")! } extension ...
- linux之vim编辑神器
设置编辑器:export EDITOR=vim 1.ctrl+x ctrl+e 创建vim临时文件 2.ctrl+[ 退回到命令模式 3.命令模式下ZZ,保存退出 4.大写I行首插入,大写A行尾插入 ...
- DAY2 raw_input() 与 input() Python
使用input和raw_input都可以读取控制台的输入,input()只能接受int,float或由它们组成的表达式: Python 2.7.5 (default, Mar 19 2014, 07: ...
- 服务器&域名那些事儿
购买的阿里云的服务器(ECS)和域名 请移步: 服务器&域名那些事儿 服务器&域名那些事儿2 github 博客
- Effective Java 学习笔记之创建和销毁对象
一.考虑用静态工厂方法代替构造器 1.此处的静态工厂方法是指返回指为类的对象的静态方法,而不是设计模式中的静态工厂方法. 2.静态工厂方法的优势有: a.使用不同的方法名称可显著地表明两个静态工厂方法 ...
- unity3d教程游戏包含的一切文件导入资源
http://www.58player.com/blog-2327-954.html 导入资源 将文件增加至工程文件夹的资源 (Assets) 文件夹后,Unity 将自动检测文件.将任何资源 (As ...