消息队列(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
管道与消息队列区别:管道基于字节流的,消息队列基于消息;
管道只能发送字符串,消息队列有类型;
管道随进程,消息队列随内核。
二、创建函数原型: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 socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- mongo实现消息队列
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程