Linux 之 IPC进程间通信(三、消息队列)

  1. 什么是消息队列
    1. 提供了一个从一个进程向另外一个进程发送一块数据的方法;
    2. 每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值;
    3. 每个数据块的最大长度是有上限的,系统上全体队列的最大总长度也有一个上限;
    4. 底层是链表;
    5. 由系统管理,进程关闭仍然在;
      1. # ipcs可以查看,共享内存、信号量同理);
      2. # Ipcrm -a删除代码创建的ipc;
  2. 消息队列的操作
    //消息队列结构体:mtype??、mtext的大小可以改变
    typedef struct Msgbuf {long mtype;  char mtext[50]; }MSGBUF;
    
    //发端
    int msgid = msgget((key_t)1001, IPC_CREAT|0777); 
    MSGBUF buf = {0};
    buf.mtype = 1;	 strcpy(buf.mtext, msg.c_str());	
    msgsnd(msgid, &buf, sizeof(buf), 0);
    
    //收端
    int msgid = msgget((key_t)1001, IPC_CREAT | 0777);
    MSGBUF buf = {0};
    msgrcv(msgid, &buf, sizeof(buf), 1, 0) > 0

    1. 结构体在#man msgsnd操作中拿到,需改变结构体名称,改变char mtext的大小适应需求,操作时赋值mtype消息类型以及mtext内容;
      • mtext可以存放结构体>>【msg_struct结构体装入数组】  
    2.  msgget((key_t)1001, IPC_CREAT|0777); 为创建新的消息队列或获取已有的消息队列;
    3. 接收端Msgrcv()为阻塞函数;
    4. 利用mtype的类型可以做哪些事情:
      • msgtype=0返回队列第一条信息
      • msgtype>0返回队列第一条类型等于msgtype的消息 
      • msgflg=IPC_NOWAIT,队列没有可读消息不等待,返回ENOMSG错误
      • ……
  3. 优缺点
    1. 可以发送块数据;
    2. 内存仍有上限。

发送端

#include
using namespace std;
#include 
#include 
#include 
#include 

// #man msgsnd 得来
typedef struct Msgbuf {
	long mtype;       /* message type, must be > 0 */
	char mtext[50];    /* message data */
}MSGBUF;



int main()
{
	//key_t 如果不存在就创建、存在就访问; 1001:键值,内部绑定一个16进制KEY
	int msgid = msgget((key_t)1001, IPC_CREAT|0777); 
	if (msgid  == -1)
	{
		perror("msgget error");
	}
	else {
		cout << "创建消息列表成功" << endl;
	}


	MSGBUF buf = {0};


	for (int i=0;i<3;i++)
	{
		char ci = i + 48;
		string msg = "hello " + ci;
		
		buf.mtype = 1;
		strcpy(buf.mtext, msg.c_str());		
		msgsnd(msgid, &buf, sizeof(buf), 0);
		cout << "发送了:" << buf.mtext << endl;
		bzero(&buf, sizeof(buf));
	}
	

	return 0;
}

接收端

#include
using namespace std;
#include 
#include 
#include 
#include 
#include 


typedef struct Msgbuf {
	long mtype;       /* message type, must be > 0 */
	char mtext[50];    /* message data */
}MSGBUF;



int main()
{
	//key_t 如果不存在就创建、存在就访问//1001 键值 内部绑定好 如果有重复的就访问
	int msgid = msgget((key_t)1001, IPC_CREAT | 0777);
	
	if (msgid == -1)
	{
		perror("msgget error");
	}
	else {
		cout << "创建消息列表成功" << endl;
	}

	MSGBUF buf = {0};
	for (int i = 0; i < 3; i++)
	{
		if (msgrcv(msgid, &buf, sizeof(buf), 1, 0) > 0)   阻塞的
			cout << "接收了: " << buf.mtext << endl;
		bzero(&buf, sizeof(buf));
	}
	return 0;
}

你可能感兴趣的:(linux,linux,c++)