进程间通信(IPC)3 ------ 消息队列 - 1
2017-12-18 14:32
218 查看
消息队列是一个存放在内核中的消息链表,由消息队列标识符标识。
向消息队列发送消息时,必须组成合理的数据结构。Linux系统定义了一个模板数据结构msgbuf:
#include <linux/msg.h>
struct msgbuf{
long mtype;
char mtext[1];
};
mtype字段代表消息类型。mtext字段指消息内容。
消息队列是随着内核的存在而存在的,每个消息队列在系统范围内对应唯一的键值。要或得一个消息队列的描述符,只需提供该消息队列的键值即可,该键值通常由函数ftok返回。该函数原型:
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname,int proj_id);
ftok函数根据pathname和proj_id这两个参数生成唯一的键值。pathname在系统中一定要存在且进程有权访问,参数proj_id的取值范围是1~255。执行成功会返回一个键值,失败返回-1。
ftok返回的键值可以提供给函数msgget。msgget()根据这个键值创建一个新的消息队列或访问一个已存在的消息队列。msgget函数的原型:
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
参数key即为ftok函数的返回值。msgflg是标志参数,一般取值IPC_CREAT,表示创建一个消息队列。
创建消息队列后,就可以对消息队列进行读写了。函数msgsnd用于向消息队列发送(写)数据。
#include <sys/msg.h>
int msgsnd(int msgid, struct msgbuf *msgp, size_t msgsz, int msgflg);
上述函数向msgid标识的消息队列发送一个消息msgp。msgsz是消息的大小。msgflg为操作标志位。msgsnd函数成功返回0,失败返回-1。
以下程序演示如何向消息队列发送消息:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUF_SIZE 256
#define PROJ_ID 32
#define PATH_NAME "." //当前路径
int main(void)
{
/*用户自定义消息缓冲*/
struct mymsgbuf {
long msgtype;
char ctrlstring[BUF_SIZE];
} msgbuffer;
int qid; /*消息队列标识符*/
int msglen;
key_t msgkey;
/*获取键值*/
if((msgkey = ftok (PATH_NAME, PROJ_ID)) == -1)
{
perror ("ftok error!\n");
exit (1);
}
/*创建消息队列*/
if((qid = msgget (msgkey, IPC_CREAT|0660)) == -1)
{
perror ("msgget error!\n");
exit (1);
}
/*填充消息结构,发送到消息队列*/
msgbuffer. msgtype = 3;
strcpy (msgbuffer.ctrlstring , "Hello,message queue");
msglen = sizeof(msgbuffer) - 4; //要发送的消息大小,不包含消息类型占用的4个字节
if(msgsnd (qid, &msgbuffer, msglen, 0) == -1)
{
perror ("msgget error!\n");
exit (1);
}
exit(0);
}
运行上述程序,即向消息队列放入了一条消息,可以通过ipcs命令查看,执行结果如下:
向消息队列发送消息时,必须组成合理的数据结构。Linux系统定义了一个模板数据结构msgbuf:
#include <linux/msg.h>
struct msgbuf{
long mtype;
char mtext[1];
};
mtype字段代表消息类型。mtext字段指消息内容。
消息队列是随着内核的存在而存在的,每个消息队列在系统范围内对应唯一的键值。要或得一个消息队列的描述符,只需提供该消息队列的键值即可,该键值通常由函数ftok返回。该函数原型:
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname,int proj_id);
ftok函数根据pathname和proj_id这两个参数生成唯一的键值。pathname在系统中一定要存在且进程有权访问,参数proj_id的取值范围是1~255。执行成功会返回一个键值,失败返回-1。
ftok返回的键值可以提供给函数msgget。msgget()根据这个键值创建一个新的消息队列或访问一个已存在的消息队列。msgget函数的原型:
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
参数key即为ftok函数的返回值。msgflg是标志参数,一般取值IPC_CREAT,表示创建一个消息队列。
创建消息队列后,就可以对消息队列进行读写了。函数msgsnd用于向消息队列发送(写)数据。
#include <sys/msg.h>
int msgsnd(int msgid, struct msgbuf *msgp, size_t msgsz, int msgflg);
上述函数向msgid标识的消息队列发送一个消息msgp。msgsz是消息的大小。msgflg为操作标志位。msgsnd函数成功返回0,失败返回-1。
以下程序演示如何向消息队列发送消息:
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUF_SIZE 256
#define PROJ_ID 32
#define PATH_NAME "." //当前路径
int main(void)
{
/*用户自定义消息缓冲*/
struct mymsgbuf {
long msgtype;
char ctrlstring[BUF_SIZE];
} msgbuffer;
int qid; /*消息队列标识符*/
int msglen;
key_t msgkey;
/*获取键值*/
if((msgkey = ftok (PATH_NAME, PROJ_ID)) == -1)
{
perror ("ftok error!\n");
exit (1);
}
/*创建消息队列*/
if((qid = msgget (msgkey, IPC_CREAT|0660)) == -1)
{
perror ("msgget error!\n");
exit (1);
}
/*填充消息结构,发送到消息队列*/
msgbuffer. msgtype = 3;
strcpy (msgbuffer.ctrlstring , "Hello,message queue");
msglen = sizeof(msgbuffer) - 4; //要发送的消息大小,不包含消息类型占用的4个字节
if(msgsnd (qid, &msgbuffer, msglen, 0) == -1)
{
perror ("msgget error!\n");
exit (1);
}
exit(0);
}
运行上述程序,即向消息队列放入了一条消息,可以通过ipcs命令查看,执行结果如下:
相关文章推荐
- 【Linux】进程间通信(IPC)之消息队列详解及测试用例
- Linux进程间通信(IPC)编程实践(五)消息队列实现回射客户/服务器
- 进程间通信(IPC)之消息队列
- 进程间通信(IPC)之————消息队列
- Linux进程间通信(IPC)编程实践(三) 详解System V消息队列(1)
- 消息队列IPC---------用途:进程间通信
- 4、进程间通信-消息队列IPC
- 进程间通信(IPC)——信号量、共享内存、消息队列
- 进程间通信(IPC)3 ------ 消息队列 - 2
- 深入理解Linux进程间通信(IPC)-- Posix消息队列
- 进程间通信(IPC)之――――消息队列
- Linux进程间通信IPC学习笔记之消息队列(Posix)
- linux 进程间通信(IPC)一消息队列
- Linux环境编程之IPC进程间通信(五):Posix消息队列1
- 进程间通信IPC:消息队列,信号量,共享内存
- Linux进程间通信IPC学习笔记之消息队列(SVR4)
- 进程学习:进程间通信(system v IPC)1.消息队列
- 进程间通信(IPC):消息队列(Message Queue)
- UNIX/Linux进程间通信IPC系列(四)消息队列
- Linux 进程间通信 (IPC) // 消息队列