IPC——应用三 消息队列

目录

一:消息队列

1.1定义

1.2设计方案

 

1.3知识了解

二:代码实现

2.1发送消息

2.2取用消息

2.3测试运行


 


一:消息队列

1.1定义

             消息队列是消息的链接表,存储在内核中,由消息队列标识符 标识。

1.2设计方案

          如图所示:先调用msgget()获取一个已存在,或者 创建一个新的队列。A进程负责发送某一类型的数据,B进程负责接受相应类型的数据。

 

1.3知识了解

      一:相关结构

        ①消息结构:

//假设发送的最长消息是512个字节
struct mymesg{
    long mtype; /* positive message type */
    char mtext[512]; /*message data, or length nbytes */
}

        ②每个消息队列都会维护一个相关数据结构: msqid_ds

//消息队列维护信息。
struct msqid_ds{
    struct ipc_perm     msg_perm;  //权限控制
    msgqnum_t           msg_qnum;  //消息队列消息数目
    msglen_t            msg_qbytes;//max # of bytes on queue
    pid_t               msg_lspid; //pid of last msgsnd()上一次发送消息的进程
    pid_t               msg_lrpid; //pid of lase msgrcv()上一次接受消息的进程
    time_t              msg_stime; //last_msgsnd() time

    time_t              msg_rtime; //last_ecvsnd() time
    time_t              msg_ctime; //last_change time
}
    

        二:相关函数

            ①函数:msgget

头文件 函数原型:

#include<sys/msg.h> 

int msgget(key_t key,int flag)

参数:

key:用于变换成一个标识符(ID)

flag:权限,以及各种控制信息的指定。

功能: 创建一个新队列或者打开一个现有队列。(主要是和其他函数配套使用,msgctl,msgsnd,msgrcv)。
函数返回值: 成功返回消息队列ID,出错返回-1.

       


            ②函数:msgctl

函数原型: int msgctl ( int msgid, int cmd , struct msqid_ds *buf);
函数参数:

1 msgid :队列编号

2 cmd :(幻数),用于指定命令,IPC_STAT,IPC_SET,IPC_RMID.

3 buf:指向结构体的指针。

函数功能: 对队列进行多种操作。

          ③函数:msgsnd

函数原型 int msgsnd ( int msgid , const void* ptr , size_t nbytes , int flag)
函数参数:

1 msgid:队列编号

2 ptr :指向一个mesg的结构体(本结构体不是头文件提供的

3 nbytes: 消息大小。

4 flag(幻数),用于指定命令,IPC_NOWAIT(非阻塞标志)。

函数功能和返回值:

将数据发送到消息队列中:

成功返回0,失败返回-1.


        ④函数:msgrcv

函数原型: int msgrcv ( int msgid , void* ptr , size_t nbytes,long type , int flag);
函数参数:

msgid 队列编号

ptr 指向一个mesg结构体指针

nbytes 消息大小

type 消息类型

flag(幻数) 用于制定命令,IPC_NOWAIT(非阻塞标志)。

函数功能和返回值: 从消息队列中取数据。 成功,返回消息队列数据部分的长度,否则返回-1。

二:代码实现

2.1发送消息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/msg.h>


typedef struct  data
{
	long type;
	char text[512];
}Data;


int main()
{
	int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);//获取
	assert(msgid != -1);


	Data val;
	memset(&val, 0, sizeof(Data));
	val.type = 1000;
	strcpy(val.text, "hello");

	msgsnd(msgid, &val, strlen(val.text)+sizeof(val.type), 0);
	
	memset(&val, 0, sizeof(Data));
	val.type = 2000;
	strcpy(val.text, "world");

	msgsnd(msgid, &val, strlen(val.text)+sizeof(val.type), 0);

	exit(0);
}

2.2取用消息

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/msg.h>


typedef struct  data
{
	long type;
	char text[512];
}Data;


int main()
{
	int msgid = msgget((key_t)1234, 0666 | IPC_CREAT);
	assert(msgid != -1);


	Data val;
	memset(&val, 0, sizeof(Data));

	//char buff[128] = {0};

	msgrcv(msgid, &val, sizeof(Data), 1000, 0);

	printf("type = %d, text = %s\n", val.type, val.text);

	exit(0);
}

2.3测试运行

猜你喜欢

转载自blog.csdn.net/genzld/article/details/84672160