msg(消息队列API)
1、消息队列的特点:
(1)传送有格式的消息流;
(2)多进程网状交叉通信时,消息队列是上上之选;
(3)能实现大规模数据的通信。
1、msgget(创建/获取消息队列)
1、头文件:#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>
2、函数原型:int msgget(key_t key, int msgflg);
3、函数形参:key:用于为消息队列生成唯一的消息队列msqid(标识符);
msgflg:指定创建时的原始权限,一般都设置为0664|IPC_CREAT。
注:①key具体设置见shmget,不同在于此处通常使用frok函数生成key。
②创建一个新的消息队列时,除了原始权限,还需要指定IPC_CREAT选项;
③如果key值没有对应任何消息队列,就会创建一个新的消息队列,此时就会用到msgflg参数,但是如果key已经对应了某个早已存在消息队列,就直接返回这个已存在消息队列的msqid(标识符),此时不会用到msgflg参数。
4、函数返回值:成功返回消息队列的msqid(标识符),失败返回-1,错误存于erron中。
5、多个进程是如何共享到同一个消息队列?
(1)fork前创建;
(2)使用ftok函数,利用与创建者相同的“路径名”和8位整形数,生成相同的key值。
6、使用ipcs命令即可查看是否创建成功,可跟接的选项有:
- a:(或什么都不跟)消息队列、共享内存、信号量的信息都会显示出来;
- m:只显示共享内存的信息;- q:只显示消息队列的信息;
- s:只显示信号量的信息。
2、msgsnd(写入消息队列)
1、头文件:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>
2、函数原型:int msgsnd(int msqid, const void msgp, size_t msgsz, int msgflg);
3、函数形参:msqid:消息队列的标识符;
msgp:存放消息的缓存的地址(struct msgbuf类型);
msgsz:消息正文大大小;
msgflg:消息发送的方式。
注:(1)msgp的struct msgbuf如下:
struct msgbuf
{
ong mtype; / 放消息编号,必须> 0 /
char mtext[msgsz]; / 消息内容(消息正文) */
};
(2)msgflg的两种方式:
① 0:阻塞发送消息,未发送成功前,该函数会一直阻塞,直到发送成功。
② IPC_NOWAIT:非阻塞方式发送消息,不管发送成功与否,函数都将返回。
4、函数返回值:成功返回0,失败返回-1,错误存于erron中。
3、msgrcv(读取消息队列)
1、头文件:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>
2、函数原型:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
3、函数形参:msqid:消息队列的标识符;
msgp:存放消息的缓存的地址(struct msgbuf类型);
msgtyp:需接收的消息的编号;
msgflg:消息发送的方式(0或IPC_NOWAIT)。
4、函数返回值:成功返回消息正文的字节数,失败返回-1,错误存于erron中。
5、功能描述:从标识符为msqid的消息队列读取消息并存于msgp中,读取后把此消息从消息队列中删除。
4、msgcnl(控制消息队列)
1、头文件:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>
2、函数原型:int msgctl(int msqid, int cmd, struct msqid_ds *buf);
3、函数形参:msqid:消息队列标识符;
cmd:控制选项;
buf:存放属性信息(控制为删除时,设置为NULL即可)。
注:cmd选项:
① IPC_STAT:将msqid消息队列的属性信息,读到第三个参数所指定的缓存。
② IPC_SET:使用第三个参数中的新设置去修改消息队列的属性。
③ IPC_RMID:删除消息队列,用不到第三个参数,用不到时设置为NULL。
4、控制功能:获取共享内存的属性信息、修改共享内存的属性信息、删除共享内存等。
5、共享内存的特点:
(1)减少进入内核空间的次数;
(2)直接使用地址来读写缓存时,效率会更高,适用于大数据量的通信。
6、使用示例:
(1)获取消息队列属性保存到buf中, cmd被设置为IPC_STAT。
struct msqid_ds buf;
msgctl(msgid, IPC_STAT, &buf);
(2)删除消息队列,cmd被设置为IPC_RMID。
msgctl(msgid, IPC_RMID, NULL);