一、概述
消息队列与 FIFO 很相似,都是一个队列结构,都可以有多个进程往队列里面写信息,多个进程从队列中读取信息。但 FIFO 需要读、写的两端事先都打开,才能够开始信息传递工作。而消息队列可以事先往队列中写信息,需要时再打开读取信息。 消息队列也分为Posix消息队列与System V消息队列,它们的区别有: ① 对Posⅸx消息队列的读总是返回最高优先级的最早消息,对 System V消息队列的读则可以返回任意指定优先级的消息。 ① 当往一个空队列放置一个消息时,Posiⅸ消息队列允许产生一个信号或启动一个线程,System V消息队列则不提供类似机制。 进程间通信多为System V消息队列 从消息队列中读出消息,消息队列中对应的数据都会被删除。 消息队列是消息的链表,存放在内存中,由内核维护。只有内核重启或人工删除消息队列时,该消息队列才会被删除。若不人工删除消息队列,消息队列会一直存在于系统中。 消息队列不依据先进先出的原则。
二、接口
2.1 msgget
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget ( key_t key, int msgflg) ;
int main ( int argc, char * argv[ ] )
{
key_t key;
int msqid;
key = ftok ( "." , 2020 ) ;
msqid= msgget ( key, IPC_CREAT| 0666 ) ;
return 0 ;
}
2.2 msgsnd
struct msgbuf {
long mtype;
char msg_text[ 30 ] ;
} mymsg;
int msgsnd ( int msqid, const void * msgp, size_t msgsz, int msgflg) ;
int main ( int argc, char * argv[ ] )
{
key_t key;
int msqid;
struct msgbuf mymsg;
key = ftok ( "." , 2020 ) ;
msqid= msgget ( key, IPC_CREAT| 0666 ) ;
mymsg. mtype = 1 ;
mymsg. msg_text[ 0 ] = 2 ;
msgsnd ( msqid, & mymsg, sizeof ( mymsg) - sizeof ( long ) , 0 ) ;
return 0 ;
}
2.3 msgrcv
ssize_t msgrcv ( int msqid, void * msgp, size_t msgsz, long msgtyp, int msgflg) ;
int main ( int argc, char * argv[ ] )
{
key_t key;
int msqid;
struct msgbuf mymsg;
ssize_t rcv_len;
key = ftok ( "." , 2020 ) ;
msqid= msgget ( key, IPC_CREAT| 0666 ) ;
rcv_len = msgrcv ( msqid, & mymsg, sizeof ( mymsg) - sizeof ( long ) , 1 , 0 ) ;
printf ( "rcv_len=%d, mymsg.msg_text=%s\n" , rcv_len, mymsg. msg_text) ;
return 0 ;
}
2.4 msgctl
struct msqid_ds {
struct ipc_perm msg_perm;
struct msg * msg_first;
struct msg * msg_last;
__kernel_time_t msg_stime;
__kernel_time_t msg_rtime;
__kernel_time_t msg_ctime;
unsigned long msg_lcbytes;
unsigned long msg_lqbytes;
unsigned short msg_cbytes;
unsigned short msg_qnum;
unsigned short msg_qbytes;
__kernel_ipc_pid_t msg_lspid;
__kernel_ipc_pid_t msg_lrpid;
} ;
int msgctl ( int msqid, int cmd, struct msqid_ds * buf) ;
int main ( int argc, char * argv[ ] )
{
key_t key;
int msqid;
struct msgbuf mymsg;
ssize_t rcv_len;
key = ftok ( "." , 2020 ) ;
msqid= msgget ( key, IPC_CREAT| 0666 ) ;
rcv_len = msgrcv ( msqid, & mymsg, sizeof ( mymsg) - sizeof ( long ) , 1 , 0 ) ;
printf ( "rcv_len=%d, mymsg.msg_text=%s\n" , rcv_len, mymsg. msg_text) ;
msgctl ( msqid, IPC_RMID, NULL ) ;
return 0 ;
}
int main ( int argc, char * argv[ ] )
{
key_t key;
int msqid;
struct msgbuf mymsg;
ssize_t rcv_len;
struct msqid_ds msg_attr;
key = ftok ( "." , 2020 ) ;
msqid= msgget ( key, IPC_CREAT| 0666 ) ;
rcv_len = msgrcv ( msqid, & mymsg, sizeof ( mymsg) - sizeof ( long ) , 1 , 0 ) ;
printf ( "rcv_len=%d, mymsg.msg_text=%s\n" , rcv_len, mymsg. msg_text) ;
msgctl ( msqid, IPC_STAT, & msg_attr) ;
printf ( "msg_stime=%d\n" , msg_attr. msg_stime) ;
printf ( "msg_rtime=%d\n" , msg_attr. msg_rtime) ;
printf ( "msg_ctime=%d\n" , msg_attr. msg_ctime) ;
return 0 ;
}