linux 消息队列

消息队列常见函数原型

int msgget(key_t key, int msgflg);
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
                      int msgflg);
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

消息队列创建

int msgget(key_t key, int msgflg);
@parma key:一个整数值,不同的进程可以通过它访问同一个消息队列,也可以通过ftok获取。特例,IPC_PRIVATE表示私有,仅限当前进程访问。
@param msgflg:与open标志类似,IPC_CREAT,IPC_EXCL

key_t k = ftok(".",1);
g_msgid = msgget(k,0666|IPC_CREAT);

消息队列的收发
消息队列收发要求:

  • 消息长度必须小于系统的规定长度
  • 累计消息数量必须小于系统规定长度
  • 消息结构体必须以一个long int整型成员变量开始
struct msgbuf {
	long int mtype;       /* message type, must be > 0 */
    char mtext[0];    /* message data */
};

发送消息

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
@param msgqid:消息队列id
@param msgp:需要发送的消息,必须以long int 开始
@param msgsz 发送消息的长度,不包含 mtype(long int)的长度
@param msgflg 只有在消息队列满或队列达到系统范围限制才有效,IPC_NOWAIT
成功返回0,失败返回-1,如果成功则把消息的一份副本放入消息队列

#define MSG_MAX 255

struct MSG{
   	long int msg_type;
   	char szBuf[MSG_MAX];
};
int msg_send(long int type,const char*info)
{struct MSG msg = {0};
   	msg.msg_type = type;
   	strcpy(msg.szBuf,info);   
   	return msgsnd(g_msgid,&msg,sizeof(struct MSG) - sizeof(long int),0);
}

收消息

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
@param msgqid:消息队列id
@param msgp:接收的消息,必须以long int 开始
@param msgsz 发送消息的长度,不包含 mtype(long int)的长度
@param msgtyp 接收消息的类型

  • 等于0:队列中的第一个消息
  • 大于0 :相同消息类型的第一个消息
  • 小于0:获取消息类型小于等于绝对值类型的第一个消息
int msg_recv(long int type,std::string &text)
{   
	struct MSG msg = {0};
   	msg.msg_type = type;
   	int val =  msgrcv(g_msgid,&msg,sizeof(struct MSG) - sizeof(long int),type,0);
   	text = msg.szBuf;
   	return val;
}

消息队列控制

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
@param msgqid:消息队列id
@param 配合buf一起设置

  • IPC_STAT:获取消息队列的关联值
  • IPC_SET:如果权限足够的情况下,把buf的值赋值给消息队列
  • IPC_RMID:删除消息队列,不管是否有进程在使用都会被立马删除和信号量一样。

注意事项

  • 消息队列属于系统资源,使用完成之后一定要删除信号量,否则会一直存在系统中(和进程是否退出无关)。
  • IPC_RMID删除消息队列的时候是真正的删除(不存在引用计数的说法),所以删除的时候一定要确保不再使用在删除。

在这里插入图片描述

扩展:可变长消息(得控制最大消息长度在系统范围之内,demo设置为255)

#define MSG_MAX 255

struct MSG{
   	long int msg_type;
   	char szBuf[0];
};

int msg_send(long int type,const char*info)
{
   	int buf_len = sizeof(long int) + strlen(info) + 1;
   	if(buf_len > MSG_MAX + sizeof(long int))
   	{
   		buf_len = MSG_MAX + sizeof(long int);
   	}
   	
   	char *szbuf = new char[buf_len];
   	memset(szbuf,0,buf_len);
    
   	struct MSG *pmsg = (struct MSG *)szbuf;
   	pmsg->msg_type = type;
   	strncpy(pmsg->szBuf,info,buf_len - sizeof(long int));
    
   	int ival =  msgsnd(g_msgid,pmsg,buf_len - sizeof(long int),0);
   	delete []szbuf;
   	return ival;
}

int msg_recv(long int type,std::string &text)
{
   	int buf_len = sizeof(long int) + MSG_MAX;
   	char *szbuf = new char[buf_len];
   	memset(szbuf,0,buf_len);
    
   	struct MSG *pmsg = (struct MSG *)szbuf;
   	pmsg->msg_type = type;
   	int val =  msgrcv(g_msgid,pmsg,buf_len - sizeof(long int),type,0);
   	text = pmsg->szBuf;
   	delete []szbuf;
   	return val;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值