system-V ipc特点
- 独立于进程
- 没有文件名和文件描述符
- IPC对象具有key和ID
消息队列用法
- 定义一个唯一key(ftok)
- 构造消息对象(msgget)
- 发送特定类型消息(msgsnd)
- 接受特定类型消息(msgrcv)
- 删除消息队列(msgctl)
消息队列函数
ftok函数
功能:获取一个key
函数原型:
key_t ftok(const char *path,int proj_id)
参数:
- path:一个合法路径
- proj_id:一个整数
返回值:
成功:合法键值
失败:-1
msgget函数
功能:获取消息队列ID
函数原型:
int msgget(key_t key,int msgflg)
参数:
- key:消息队列的键值
- msgflg:
- IPC_CREAT:如果消息队列不存在,则创建
- mode:访问权限
返回值:
成功:该消息队列的ID
失败:-1
msgsnd函数
功能:发送消息到消息队列
函数原型:
int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);
参数:
-
msqid:消息队列ID
-
msgp:消息缓存区
-
struct msgbuf
{
long mtype; //消息标识
char mtext[1]; //消息内容
}
-
-
msgsz:消息正文的字节数
-
msgflg:
- IPC_NOWAIT:非阻塞发送
- 0:阻塞发送
返回值:
成功:0
失败:-1
msgrcv函数
功能:从消息队列读取消息
函数原型:
ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg)
参数:
-
msqid:消息队列ID
-
msgp:消息缓存区
-
msgsz:消息正文的字节数
-
msgtyp:要接受消息的标识
-
msgflg:
-
IPC_NOWAIT:非阻塞读取
-
MSG_NOERROR:截断消息
-
0:阻塞读取
-
返回值:
成功:0
失败:-1
msgctl函数
功能:设置或获取消息队列的相关属性
函数原型:
int msgctl(int msgqid,int cmd,struct maqid_ds *buf)
-
msgqid:消息队列的ID
-
cmd
- IPC_STAT:获取消息队列的属性信息
- IPC_SET:设置消息队列的属性
- IPC_RMID:删除消息队列
-
buf:相关结构体缓冲区
实现代码
msg_recv
#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;
struct message msg;
/*创建key
key_t key
if ((key= fotk("/tmp", 11)) == -1)
{
perror("fotk");
exit(1);
}
*/
/*创建消息队列*/
if ((qid = msgget((key_t)1234, IPC_CREAT|0666)) == -1)
{
perror("msgget");
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 %ld : %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);
}
else
{
printf("Delete msg qid: %d.\n", qid);
}
exit(0);
}
msg_send
#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;
struct message msg;
/*创建消息队列*/
if ((qid = msgget((key_t)1234, IPC_CREAT|0666)) == -1)
{
perror("msgget\n");
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)
{
printf("\nGet message end.\n");
exit(1);
}
msg.msg_type = getpid();
/*添加消息到消息队列*/
if ((msgsnd(qid, &msg, strlen(msg.msg_text), 0)) < 0)
{
perror("\nSend message error.\n");
exit(1);
}
else
{
printf("Send message.\n");
}
if (strncmp(msg.msg_text, "quit", 4) == 0)
{
printf("\nQuit get message.\n");
break;
}
}
exit(0);
}