消息队列:消息队列是一些消息的列表,用户可以从消息队列中读取和添加消息,消息队列具有FIFO的特性,但可以实现消息的随机查询,比FIFO有更大的优势,这些消息都是存在于内核中,由“队列ID”来标识
消息队列的实现包括创建或打开消息队列,添加消息,读取消息,控制消息四种操作
创建或打开消息:使用msgget(),这里创建的消息队列的数量受到系统消息队列数量的限制
添加消息:使用msgsnd(),他把消息添加到消息队列的末尾
读取消息:使用msgrcv(),他把消息从消息队列中取走,与FIFO不同的是他可以取走某一条消息
控制消息:使用msgctl()控制消息队列,根据参数的不同可以完成多项功能
msgget()函数语法如下:
msgsnd()函数语法如下:
msgrcv()函数语法如下:
msgctl()函数语法如下:
这个例子说的两个进程通过消息队列进行通信:
发送端代码:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 512
struct message
{
long msg_type ;//消息类型
char msg_text[BUFFER_SIZE] ;//消息内容
};
int main()
{
int qid ;
key_t key ;
struct message msg ;
//ftok()函数根据路径和关键字生产标准的key
if ((key = ftok(".", 'a')) == -1)
{
perror("ftok") ;
exit(1) ;
}
//创建消息队列
if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
{
perror("msgget") ;
exit(1) ;
}
printf("open queue %d\n", qid) ;
while(1)
{
printf("Enter some message to the queue:") ;
if (fgets(msg.msg_text, BUFFER_SIZE, stdin) == NULL)
{
puts("no message") ;
exit (1) ;
}
//将消息类型设置成进程的id
msg.msg_type = getpid() ;
//向消息队列中添加消息
if (msgsnd(qid, &msg, strlen(msg.msg_text), 0) < 0)
{
perror("messaged posted") ;
exit(1) ;
}
if (strncmp(msg.msg_text, "quit", 4) == 0)
{
break ;
}
}
exit(0) ;
}
接收端:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFER_SIZE 512
struct message
{
long msg_type ;
char msg_text[BUFFER_SIZE] ;
};
int main()
{
int qid ;
key_t key ;
struct message msg ;
if ((key = ftok(".", 'a')) == -1)
{
perror("ftok") ;
exit(1) ;
}
if ((qid = msgget(key, IPC_CREAT|0666)) == -1)
{
perror("msgset") ;
exit(1) ;
}
printf("open queue%d\n", qid) ;
do
{
memset(msg.msg_text, 0, BUFFER_SIZE) ;
//从消息队列中获取消息
if (msgrcv(qid, (void *)&msg, BUFFER_SIZE, 0, 0) < 0)
{
perror("msgrcv") ;
exit(1) ;
}
printf("the message from process %d:%s", msg.msg_type, msg.msg_text) ;
}while(strncmp(msg.msg_text, "quit", 4)) ;
//删除消息队列
if ((msgctl(qid, IPC_RMID, NULL)) < 0)
{
perror("msgctl") ;
exit(1) ;
}
exit(0) ;
}
运行结果如下:
发送端:
接接收端:
由此可以看出两个进程使用id为65535的消息队列进行通信,消息队列内核自动实现了同步,所以不需要额外提供同步机制来自http://bbs.csdn.net/topics/300199658