Linux消息队列编程示例


一、概念

消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;有读权限的进程则可以读走消息。读走就没有了。消息队列是随内核持续的。 只有内核重启或人工删除时,该消息才会被删除。在系统范围内,消息队列与键值唯一对应。

二、步骤及思路

1、取得键值
2、打开、创建消息队列
3、发送消息
4、接收消息

下面具体看看:

1、取得键值

复制代码
代码如下:

key_t ftok(char *pathname, char proj)

   头文件为<sys/ipc.h>。返回文件名对应的键值,失败返回 -1。proj是项目名,随便写,不为0就行。
   fname就是你指定的文件名(已经存在的文件名)。需要有-t 的权限,或用root权限执行,通常设为/tmp或设为" . "。这里我感觉不用这个函数也行,因为key值可以自己指定,例如: #define KEY_MSG 0x101
2、打开、创建消息队列

复制代码
代码如下:

int msgget(key_t key, int msgflg)

  头文件为<sys/msg.h>。key由ftok获得。

  msgflg有:

IPC_CREAT 创建新的消息队列,应配有文件权限0666。
IPC_EXCL  与IPC_CREAT一同使用,表示如果要创建的消息队列已经存在,则返回错误。

IPC_NOWAIT 读写消息不阻塞。
 
  当没有与key相对应的消息队列并且msgflg中包含了IPC_CREAT标志 或 key的参数为IPC_PRIVATE 时,创建一个新的消息队列。
3、发送消息

复制代码
代码如下:

int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg)

    向消息队列发送一条消息。msqid为消息队列的id,msgp为存放消息的结构体。msgsz是消息的长度,和数组的大小不一样哦。msgflg为消息标志,通常为0,也可以为IPC_NOWAIT。出错返回 -1。
 
消息格式

复制代码
代码如下:

struct msgbuf {
long mtype;
char mtext[100];
};

4、接收消息

复制代码
代码如下:

int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg)

    从msqid代表的消息队列中读取一个msgtyp类型的消息,并把消息存储在msgp指定的msgbuf结构中。读取后队列中的消息将会删除。size为结构体中数据的大小,不要计算msgtyp。出错返回 -1。
三、举例
创建一消息队列,子进程发数据,父进程收数据。实现向队列中存放数据与读取数据。


复制代码
代码如下:

#include<stdio.h>
#include<sys/msg.h>
#include<fcntl.h>
#include<stdlib.h>
#include<string.h>
#define max 100</p> <p>struct haha{
long mtype;
char data[max];
};</p> <p>int main(int argc,char *argv[]){
int pid;
if(argc!=2){
printf("Usage: msg [Message]\n");
return -1;
}
key_t key;
if((key=ftok("/tmp",'g'))<0){ //这里文件夹必须存在,有t属性并且上级目录也要有t属性
printf("Getting key error! \n");
return -1;
}
int mgsid;
if((mgsid=msgget(key,IPC_CREAT|0666))==-1){ //key值随便写一个数也能用
printf("mgs queue create error\n");
return -1;
}
pid=fork();
if(pid <0){
printf("fork create error!\n");
_exit(1);
}
if(pid == 0){
printf("welcome in child process\n Sending the message......\n");
sleep(1);
struct haha hehe;
hehe.mtype=getppid();
strcpy(hehe.data,argv[1]);
if(msgsnd(mgsid,&hehe,sizeof(hehe.data),0)<0){ //此处注意长度
printf("Sending error!!!\n");
_exit(1);
}else {
printf("Sending complete!\n");
_exit(0);
}
}else{
wait(NULL);
printf("welcome in parents process\n Receiving the message......\n");
sleep(1);
struct haha gaga;
if(msgrcv(mgsid,&gaga,max,getpid(),0)<0){
printf("Receiving error!!!\n");
_exit(1);
}else {
printf("Receiving complete!\n");
printf("The message is %s \n",gaga.data);
}
}
return 0;
}



相关阅读:
使用MySQL MySqldump命令导出数据时的注意事项
微软发布Linux Integration Services 4.0 更新下载
JavaScript创建闭包的两种方式的优劣与区别分析
CSS控制让每行显示4个图片的样式
PHP实现在线阅读PDF文件的方法
PHP实现根据时间戳获取周几的方法
JSP学习笔记
MySQL分页技术、6种分页方法总结
Win10 Cortana中惊现Uber 目前还不能正常运行
微信开放平台之网站授权微信登录功能
Java图像处理工具类
javascript从定义到执行 你不知道的那些事
JS判断变量是否为空判断是否null
javascript 判断字符串是否包含某字符串及indexOf使用示例
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 SQL jQuery C# C++ java Android IOS oracle MongoDB SQLite wamp 交通频道 作文范文 我是一名小交警作文 物业公司总经理述职报告 关于六年级下册手抄报资料 孩子在永远的微笑 办公室表格怎么制作 樱花之舞 小学六年级作文350字:多彩的校园 2015年婚前协议书格式 2015年漳州市中考语文作文范文赏析:守护梦想(范文一) 春天的味道350字 小狗 张金涛 留学申请表 在生活中体验你的爱情 大学生参加党校培训思想汇报 信其能,任其行 做梦想着亲人作文900字 温馨节日(2) 工人思想汇报 美艳绝伦之十五 远行在身后 每一个跑者都有一颗坚强的心 绿光,一种美丽的欺骗作文800字 小学二年级作文300字:雨后的野外 我的猫咪------兰花花 咏笙 两年奠 公务员考核鉴定意见 高温天气防暑短信 【精品】淘宝中秋节活动方案 人文学院学生会例会制度条例 第一次盛粥 回顾两茫茫,眉似远山长 一念相思,一生心疼 励志语录摘抄 满庭芳(和同漕彦约送秦寿之) 关于爱国的诗句 有关于青春的名言 童年生活作文300字 《焦裕禄》观后感作文 小学六年级作文500字:秋千 作文 月牙儿弯弯 《查理九世》——读后感作文800字 2012年度动力车间工作总结 创建“廉政”法院工作总结5年工作思路_政务工作总结 拉手 我,一个人 小学二年级作文350字:多姿多彩的课间 我最喜欢的鸟作文350字 经典朋友祝福语 描写青草的好段

Copyright © 2016 phpStudy |