linux消息队列

相关函数

#include <sys/types.h> 

#include <sys/ipc.h> 

#include <sys/msg.h>
创建消息队列
int msgget(key_t key, int msgflg);

创建或者打开一个消息队列,成功返回消息队列的句柄,失败返回-1

需要提供给函数key(键值)和msgflag操作类型。

所有使用这个消息队列的进程需要使用相同的键值(一个整形数字),保证打开的是同一个消息队列。

操作类型参数的范围:

/* Mode bits for `msgget', `semget', and `shmget'.  */
#define IPC_CREAT	01000		/* Create key if key does not exist. */
#define IPC_EXCL	02000		/* Fail if key exists.  */
#define IPC_NOWAIT	04000		/* Return error on wait.  */
向消息队列中发送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//成功返回0,失败返回-1

参数:

msgid 消息队列的句柄,

msgp 要发送的消息结构体指针,

msgsz 发送的消息大小(不包括消息类型),

msgflag 操作类型

解释:

当消息队列中空间被占满时,msgsnd会被阻塞住。但可以将msgflag设置为IPC_NOWAIT,当消息队列满时,会立即返回错误。

从消息队列中接收消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
//成功返回接收到的长度,失败返回-1
参数:
msgid 消息队列的句柄
msgp 接收消息存放位置
msgsz 接收的消息大小
msgtype 消息类型
msgflag 操作类型

参数解释:

msgtype=0 接收消息队列中的第一条消息

msgtype>0 接收消息队列中消息类型等于msgtype的第一条消息

msgtype<0 接收消息队列中类型值小于msgtype绝对值的第一条消息

接收的msgflag操作类型参数,一般设置为0,可以让队列中没有消息时,接收一直阻塞。

消息队列的控制
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

参数:

msgid 消息队列句柄

cmd 命令,一般使用IPC_RMID删除消息队列

buf 一般为NULL

消息结构体

结构体可以自己定义,但是最前的成员必须是一个long型数据,表示消息类型。

代码

send.c

#define MSGKEY 1001
#define MSG_TYPE 1
 
struct msgbuf
{
	long mtype;     /* message type, must be > 0 */
	double Lat;
	double Lon;
	double Hgt;
};

int main()
{
	int msgid;
	int ret;
	struct msgbuf mbuf;
 
	msgid = msgget(MSGKEY, 0);	//打开消息队列
	if (-1 == msgid)
	{
		perror("msgget");
		exit(1);
	}
 
	{
		for(unsigned int i=0;i<10;i++)
		{
                    mbuf.Lat += 10.11;
                    mbuf.Hgt += 100.0;
		    mbuf.mtype = MSG_TYPE;
 
		    ret = msgsnd(msgid, &mbuf, sizeof(mbuf)-sizeof(mbuf.mtype), 0);
		    if (-1 == ret)
		    {
			perror("msgsnd");
			exit(1);
		    }
                    sleep(1);
		}
	}
	sleep(1);
	msgctl(msgid, IPC_RMID, NULL);//销毁消息队列
	return 0;
}

recv.c

#define MSGKEY 1001
#define MSG_TYPE 1
 
struct msgbuf
{
	long mtype;     /* message type, must be > 0 */
	double Lat;
	double Lon;
	double Hgt;
};
 
 
int main()
{
	int msgid;
	int ret;
	struct msgbuf mbuf;
 
	msgid = msgget(MSGKEY, IPC_CREAT | IPC_EXCL);	//打开消息队列,如果已经存在则报错
	if (-1 == msgid)
	{
		perror("msgget");
		exit(1);
	}
 
	while (1)
	{
		memset(&mbuf, 0, sizeof(mbuf));
		ret = msgrcv(msgid, &mbuf, sizeof(mbuf)-sizeof(mbuf.mtype), MSG_TYPE,0);
		if (-1 == ret)
		{
			perror("msgrcv");
			exit(1);
		}

		printf("queue recv Lat=%lf,Lon=%lf,Hgt=%lf\n",mbuf.Lat, mbuf.Lon, mbuf.Hgt);
	}
	return 0;
}
posted @ 2021-10-31 09:27  WuYunTaXue  阅读(1656)  评论(0编辑  收藏  举报