栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

linux系统c语言进程通信--消息队列(封装好的接口)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux系统c语言进程通信--消息队列(封装好的接口)

linux系统c语言进程通信--消息队列

一、linux下的进程通信说明二、自定义封装好的接口(简单好用)

1、源码免费下载2、头函数说明3、demo测试4、接口源码
进程通信–消息列队是linux下经常用到的通信方式,可用于多个进程之间的通信,也可在一个进程内通信(相当于队列的方式)。我简单封装记录了一下,方便自己以后查阅

一、linux下的进程通信说明

Linux操作系统system V进程间通信,主要有三种方式:
1、消息队列;
2、信号量;
3、内存共享

Linux的消息队列可自定义发送和接收不同类型的数据,主要涉及到3个函数:

1、创建消息队列

 在使用一个消息队列前,需要使用msgget函数创建该消息队列,其函数声明:

 extern int magget(key_t _key,int _msgflg) _THROW;

 第一个参数key由ftok创建的key值;

 第二个参数_msgflg的低位用来确定消息队列的访问权限。

2、发送消息到消息队列

 extern int msgsnd(int _msqid , _const void * _msgq, size_t _msgsz , int _msgflg );

 第一个参数msgid为指定的消息队列标识符(由msgget生成的消息队列标识符),即将消息添加到哪个消息队列中。

 第二个参数msgq为指向的用户定义缓冲区。

 第三个参数为接收消息的大小,其数据类型为:size_t,即unsigned int类型。其大小为0到系统对消息队列的限制值。

 第四个参数用来执行在达到系统为消息队列所定的界限(如达到字数限制)时应采取的操作。

3、从消息队列接收信息

extern int msgrcv(int _msgid, void * _msgq,size_t _msgsz,long int _msgtyp,int _msgflg);

第一个参数为读的对象,即从哪个消息队列获取信息。

第二个参数为一个临时消息数据结构,用来保存读取的信息。
二、自定义封装好的接口(简单好用)

1、源码免费下载

点击下载:封装好的进程通信接口和demo

编译:
cd msg_que_test
make
可得到3个可执行文件send(发送端)、recv1、recv2

2、头函数说明

只有简单的5个函数(创建、发送、堵塞接收、非堵塞接收、删除)
经过了并发测试,放心使用就对了

#ifndef _MSG_QUE_H_
#define _MSG_QUE_H_


//#define MSG_FILE "/tmp/msgque"  //进程通信共有的文件
//#define MAX_TEXT 1024*10  //发送消息最大长度
#define MAX_TEXT 1024*100  //发送消息最大长度

typedef enum { //类型(类型必须大于0)
	NONE = 0,
	TYPE_1_MSG,
	TYPE_2_MSG,
	TYPE_3_MSG,
	TYPE_4_MSG,
	TYPE_5_MSG,
}MSG_QUE_TYPE;
	
struct msg_form 
{
	long mtype;//类型必须大于0
	char mtext[MAX_TEXT];//消息
};


int sutpc_creatMsgQue(int key);

	
int sutpc_deleteMsgQue(int msgid);

	
int sutpc_sndMsgQue(int msgid, int type, char *msgBuff, int length);


int sutpc_blockRcvMsgQue(int msgid, int type, char *rcvBuff, int rcvSize);

	
int sutpc_noBlockRcvMsgQue(int msgid, int type, char *rcvBuff, int rcvSize);
#endif

3、demo测试

send.c-发送端(发送两种类型的数据)

#include 
#include 
#include 
#include 
#include 
#include 
#include "msg_que.h"


#define MSG_QUE_KEY_ID 1996 //消息队列标识




int main () 
{

	int msgid = 0;
	char msgBuff[256] = {0};
	msgid = sutpc_creatMsgQue(MSG_QUE_KEY_ID);
	int i = 0;
	
	while (1) {
		sprintf(msgBuff, "%d", i);
		sutpc_sndMsgQue(msgid, TYPE_1_MSG, msgBuff, strlen(msgBuff));
		
		sprintf(msgBuff, "zhou-%d-yi", i);
		sutpc_sndMsgQue(msgid, TYPE_2_MSG, msgBuff, strlen(msgBuff));
		i++;
		sleep(1);
	}

	sutpc_deleteMsgQue(msgid);
	
	return 0;
}

recv1.c-接收端接收类型1的数据

#include 
#include 
#include 
#include 
#include 
#include 
#include "msg_que.h"


#define MSG_QUE_KEY_ID 1996 //消息队列标识




int main () 
{

	int msgid = 0;
	char rcvBuff[256] = {0};
	msgid = sutpc_creatMsgQue(MSG_QUE_KEY_ID);

	
	while (1) {
		memset(rcvBuff, 0, sizeof(rcvBuff));
		sutpc_blockRcvMsgQue(msgid, TYPE_1_MSG, rcvBuff, 256);
		printf("TYPE_1_MSG:%sn", rcvBuff);
	}

	sutpc_deleteMsgQue(msgid);
	return 0;
}

recv2.c-接收端接收类型2的数据

#include 
#include 
#include 
#include 
#include 
#include 
#include "msg_que.h"


#define MSG_QUE_KEY_ID 1996 //消息队列标识




int main () 
{

	int msgid = 0;
	char rcvBuff[256] = {0};
	msgid = sutpc_creatMsgQue(MSG_QUE_KEY_ID);

	
	while (1) {
		memset(rcvBuff, 0, sizeof(rcvBuff));
		sutpc_blockRcvMsgQue(msgid, TYPE_2_MSG, rcvBuff, 256);
		printf("TYPE_2_MSG:%sn", rcvBuff);
	}
	
	sutpc_deleteMsgQue(msgid);
	return 0;
}

4、接口源码

msg_que.c

#include 
#include 
#include 
#include 
#include 
#include "msg_que.h"




int sutpc_creatMsgQue(int key)
{
	int msqid;

	
    printf("Message Queue - Server key is: %d.n", key);

    //创建消息队列,第一个参数 key:为由ftok创建的key值,第二个参数 msgflg:用来确定消息队列的访问权限。
    if ((msqid = msgget(key, IPC_CREAT|0777)) < 0) { //第二个参数 用来确定消息队列的访问权限。返回消息队列的标识 如果这个消息队列已经存在,则返回ID
        perror("msgget error");
        return -1;
    }

	return msqid;
}

	
int sutpc_deleteMsgQue(int msgid)
{
	int ret = 0;

	ret = msgctl(msgid, IPC_RMID, NULL);
	if (ret == -1) {
		perror("msgctl");
		return -1;
	}
	
	return 0;
}

	
int sutpc_sndMsgQue(int msgid, int type, char *msgBuff, int length)
{
	int ret = 0;
	struct msg_form msgbuf;
	memset(&msgbuf, 0, sizeof(msgbuf));
	
	if(length > sizeof(msgbuf.mtext)){
    	printf("msg length is too longn");
    	return -1;
    }
	msgbuf.mtype = type;	
	strcpy(msgbuf.mtext, msgBuff);
	ret = msgsnd(msgid, (void*)&msgbuf, length, IPC_NOWAIT);//非堵塞
	if (ret == -1){
		perror("msgsnd");
		return -1;
	}

	return 0;
}

	
int sutpc_blockRcvMsgQue(int msgid, int type, char *rcvBuff, int rcvSize)
{
	int ret = 0;
	struct msg_form msgbuf;
	memset(&msgbuf, 0, sizeof(msgbuf));

	ret = msgrcv(msgid, (void*)&msgbuf, sizeof(msgbuf.mtext), type, 0);//没有指定IPC_NOWAIT,进程阻塞,挂起执行直至:有了指定类型的消息
	if (ret == -1) {
		perror("msgrcv");
		return -1;
	}
	
	strcpy(rcvBuff, msgbuf.mtext);
	return 0;
}


	
int sutpc_noBlockRcvMsgQue(int msgid, int type, char *rcvBuff, int rcvSize)
{
	int ret = 0;
	struct msg_form msgbuf;
	memset(&msgbuf, 0, sizeof(msgbuf));

	ret = msgrcv(msgid, (void*)&msgbuf, rcvSize, type, IPC_NOWAIT);//不阻塞
	if (ret == -1) {
		perror("msgrcv");
		return -1;
	}
	
	strcpy(rcvBuff, msgbuf.mtext);
	return 0;
}

msg_que.h

#ifndef _MSG_QUE_H_
#define _MSG_QUE_H_


//#define MSG_FILE "/tmp/msgque"  //进程通信共有的文件
//#define MAX_TEXT 1024*10  //发送消息最大长度
#define MAX_TEXT 1024*100  //发送消息最大长度

typedef enum { //类型(类型必须大于0)
	NONE = 0,
	TYPE_1_MSG,
	TYPE_2_MSG,
	TYPE_3_MSG,
	TYPE_4_MSG,
	TYPE_5_MSG,
}MSG_QUE_TYPE;
	
struct msg_form 
{
	long mtype;//类型必须大于0
	char mtext[MAX_TEXT];//消息
};

int sutpc_creatMsgQue(int key);
int sutpc_deleteMsgQue(int msgid);
int sutpc_sndMsgQue(int msgid, int type, char *msgBuff, int length);
int sutpc_blockRcvMsgQue(int msgid, int type, char *rcvBuff, int rcvSize);
int sutpc_noBlockRcvMsgQue(int msgid, int type, char *rcvBuff, int rcvSize);
#endif

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/767724.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号