您的位置:首页 > 运维架构 > Linux

消息队列(msg)

2016-04-17 17:33 465 查看
一、消息队列:从一个进程向另一个进程发送数据块,读取不一定是先入先出。

管道与消息队列区别:管道基于字节流的,消息队列基于消息;
管道只能发送字符串,消息队列有类型;

管道随进程,消息队列随内核。

二、创建函数原型:int msgget(key_t key, int msgflg); //key由ftok生成,IPC_CREAT|IPC_EXCL
接收消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
发送消息:int msgsnd(int msqid, const void *magp, size_t msgsz, int msgflg)
删 除:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
/*
* msqid:消息队列标识码; msgp:指向缓冲区的指针,暂时存储消息;
* msgsz:消息大小; msgtyp:读取的消息形态,0表示消息队列中的消息都会读取

* msgflg:0表示队列满或者空时,采用阻塞等待方式;IPC_NOWAIT表示不做等待,立即返回

*/
struct msgstru

{
long mtype;

char metext[];

}

三、代码实现:
//comm.h
#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/types.h>
#include<sys/msg.h>
#include<time.h>

#define _SIZE_ 1024
#define _FILEPATH_ ".tmp"
#define _ID_ 0x666

typedef struct _msg_info
{
long mtype;
char mtext[_SIZE_];
}msginfo;

int creat_msg();
int get_msg();
int destroy_msg(int);
int rec_msg(int, long);
int send_msg(int, long);
//comm.c
#include"comm.h"

static int com_creat_msg(int flags)
{
key_t _key = -1;
_key = ftok(_FILEPATH_, _ID_);
if(_key == -1)
{
perror("ftok");
return -1;
}

int _msg_id = -1;
_msg_id = msgget(_key, flags);
if(_msg_id == -1)
{
perror("msgget");
return -1;
}

return _msg_id;
}

int creat_msg()
{
int flags = IPC_CREAT|IPC_EXCL|0666;
return com_creat_msg(flags);
}

int get_msg()
{
return com_creat_msg(IPC_CREAT);
}

int rec_msg(int _msg_id, long mtype)
{
msginfo _info;
memset(_info.mtext, '\0', sizeof(_info.mtext));
if(msgrcv(_msg_id, &_info, sizeof(_info.mtext), mtype, 0) < 0)
{
perror("msgrcv");
return -1;
}
printf("%s\n",_info.mtext);
return 0;
}

int send_msg(int _msg_id, long mtype)
{
msginfo _info;
memset(_info.mtext, '\0', sizeof(_info.mtext));
fgets(_info.mtext, _SIZE_, stdin);
if(strncasecmp(_info.mtext, "quit", 4) == 0)
{
return 0;
}
_info.mtype = mtype;
if(msgsnd(_msg_id, &_info, sizeof(_info.mtext), 0) < 0)
{
perror("msgsnd");
return -1;
}
return 0;
}

int destroy_msg(int _msg_id)
{
if(msgctl(_msg_id, IPC_RMID, NULL) < 0)
{
perror("msgctl");
return -1;
}
return 0;
}
//ser.c
#include"comm.h"

int main()
{
int _msg_id = get_msg();
while(1)
{
printf("client:>");
rec_msg(_msg_id, 1);
fflush(stdout);

printf("server:>");
send_msg(_msg_id, 2);
}
return 0;
}
//cli.c
#include"comm.h"

int main()
{
int _msg_id = creat_msg();
while(1)
{
fflush(stdout);
printf("client:>");
send_msg(_msg_id, 1);

printf("server:>");
rec_msg(_msg_id, 2);
}
destroy_msg(_msg_id);
return 0;
}
四、实现结果:






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux 消息队列 msg