一、linux下的进程通信说明二、自定义封装好的接口(简单好用)
1、源码免费下载2、头函数说明3、demo测试4、接口源码
进程通信–消息列队是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
只有简单的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的数据
#include4、接口源码#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; }
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



