进程间的通讯方式_消息队列

消息队列:提供了一种从一个进程向另一个进程发送一个数据块的方法,而且每个数据块都被认为含有一个类型,接收进程可以独立地接受含有不同类型值得数据块。

       消息:数据 & 类型

       队列:一种数据结构,先进先出

       消息队列:是一种临时存储信息的队列,完成进程间的数据传递,优先级队列

消息队列的特点:

      1.与信号量相比:都以内核对象来确保多进程访问同一个消息队列,信号量进行同步控制,消息队列发送实际数据。

      2.与管道相比:管道发送的数据没有类型,读取数据端无差别从管道中按照数据的前后顺序读取数据,消息队列数据有类型,读端可以根据数据类型读取特定数据。

消息队列的相关操作:

       创建或获取:int msgget((key_t)key, int flag);

                             key:键值      

                             flag:权限以及控制,由9个权限标志组成。由IPC_CREAT定义的一个特殊位必须和权限标志按位或才能创建一个新的消息队列。

                                       如果消息队列已经存在,则直接获取;如果不存在,则创建。

                             成功时 msgget 函数返回一个正整数,即队列标识符,失败时返回-1;

       发送消息:int msgsnd(int msgid, void *ptr, size_t size, int flag);

                         msgid:是由 msgget 函数返回的 消息队列标识符

                         ptr:指向一个结构体:类型+数据

                         size:数据的大小

                         成功时这个函数返回 0,失败时返回 -1。如果调用成功,消息队列数据的一份副本将被放到消息队列中。

       获取消息:int msgrcv(int msgid, void *ptr, size_t size, long type, int flag);

       删除消息队列:int msgctl(int msgid, int cmd, struct msgid_ds *buff);

                                cmd:是将要采取的动作,它可以取 3 个值:IPC_STAT,IPC_SET,IPC_RMID

                                migid_ds 的结构体至少包含一下成员:

                                      struct msgid_ds

                                      {

                                          uid_t msg_perm.uid;

                                          uid_t msg_perm.gid;

                                          mode_t msg_perm.mode;

                                      }

                                成功是它返回 0,失败时返回 -1。

练习:A 进程负责根据用户选择的数据类型(long)发送用户输入的数据(char *),B 进程读取1000类型的数据,C 进程读取2000类型的数据

A进程代码如下:

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

struct msgbuff
{
	long type;
	char data[128];
};

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

	struct msgbuff buffer;
	buffer.type = 1000;
	strcpy(buffer.data, "hello");

	msgsnd(msgid, &buffer, strlen(buffer.data), 0);

	buffer.type = 2000;
	strcpy(buffer.data,"world");

	msgsnd(msgid, &buffer, strlen(buffer.data), 0);
}

B 进程代码如下:

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

struct msgbuff
{
	long type;
	char data[128];
};

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

	struct msgbuff buffer;
	memset(&buffer, 0, sizeof(buffer));

	msgrcv(msgid, &buffer, 127, 1000, 0);

	printf("%s\n", buffer.data);
}

C 进程代码如下:

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

struct msgbuff
{
	long type;
	char data[128];
};

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

	struct msgbuff buffer;
	memset(&buffer, 0, sizeof(buffer));

	msgrcv(msgid, &buffer, 127, 2000, 0);

	printf("%s\n", buffer.data);
}

测试运行结果如下:





在Linux下,QT可以使用mqueue消息队列实现进程通信。为了使用消息队列,需要包含头文件#include <mqueue.h>,并在pro文件中添加编译选项LIBS = -lrt。消息队列具有以下特征:可以设置最大消息个数和每个消息的最大字节数,可以向消息队列中写入多条消息,而其他进程读取一条消息后,消息队列就会删除这条消息。 要发送消息到消息队列中,可以使用mq_send函数。该函数的原型是int mq_send(mqd_t mqdes, const char *ptr, size_t len, unsigned int prio)。其中,mqdes是打开消息队列时返回的消息队列描述符,ptr是指向要发送的消息的指针,len是消息的长度,prio是消息的优先级。 在应用中使用消息队列进行进程通信,可以发现消息队列具有强大的功能。它可以方便地管理线程,实现互斥量和条件变量等功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Qt实现IPC进程通信-mqueue消息队列](https://blog.csdn.net/weixin_40355471/article/details/113178838)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [进程通信之深入消息队列的详解](https://download.csdn.net/download/weixin_38517212/14872197)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值