Linux学习笔记28——消息队列
一 关于消息队列
消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法,而且,每个数据块都被认为含有一个类型,接收进程可以独立地接受含有不同类型值的数据块。可以通过发送消息来几乎完全避免命名管道的同步和阻塞问题。但是,与管道一样,每个数据块都有一个最大长度的限制,系统中所有队列所包含的全部数据块的总长度都有一个上限。
与命名管道相比,消息队列的优势是,它独立于发送和接受进程而存在,这消除了在同步命名管道的打开和关闭时可能产生的一些困难。
二 相关函数
#include <sys/msg.h>
//msgget函数创建和访问一个消息队列
int msgget(key_t key,
int msgflg //由IPC_CREAT定义的一个特殊位必须和权限标志按位或才能创建一个新的消息队列,在设置IPC_CREAT标志时,如果给出的是一个已有消息队列的键也不会产生错误。如果消息队列已有,则IPC_CREAT标志就被悄悄地忽略掉。
); //成功时msgget函数返回一个正整数,即队列标识符,失败时返回-1 //msgsnd函数用来把消息添加到消息队列中
int msgsnd(int msqid, //是由msgget函数返回的消息队列标识符
const void *msg_ptr, //是一个指向准备发送消息的指针
size_t msg_sz, //是msg_ptr指向的消息的长度,它不包括长整型消息类型成员变量的长度
int msgflg //是控制在当前消息队列满或队列消息到达系统范围的限制时将要发生的事情。
//如果msgflg中设置了IPC_NOWAIT标志,函数将立刻返回,不发送消息并且返回值为-1.如果msgflg中IPC_NOWAIT标志被清除,则发送进程将挂起以等待队列中腾出可用空间。
);
//msgrcv函数从一个消息队列中获取消息
int msgrcv(int msqid, //由msgget函数返回的消息队列标识符
void *msg_ptr, //是一个指向准备接受消息的指针,消息必须以一个长整数型成员变量开始
size_t msg_sz, //是msg_ptr指向的消息的长度,它不包括长整型消息类型成员变量的长度
long int msgtype, //如果值为0,就获取队列中的第一个可用消息;如果它的值大于零,将获取具有相同消息类型的第一个消息;如果它的值小于零,将获取消息类型等于或小于msgtype的绝对值的第一个消息
int msgflg //用于控制当队列中没有相应类型的消息可以接受时将发生的事情
); //成功时msgrcv函数返回放到接收缓存区中的字节数,消息被复制到由msg_ptr指向的用户分配的缓存区中,然后删除消息队列中的对应消息,失败时返回-1 //msgctl函数与共享内存的控制函数相似
int msgctl(int msqid, //是msgget返回的消息队列标识符
int cmd, //将要采取的动作
struct msqid_ds *buf
); //成功时返回0,失败时返回-1,如果删除消息队列时,某个进程正在msgsnd或msgrcv函数中等待,这两个函数将失败
msgctl中第二个参数要采取的动作:
IPC_STAT:把msqid_ds结构中的数据设置为消息队列的当前关联值
IPC_SET:如果进程有足够的权限,就把消息队列的当前关联值设置为msqid_ds结构中给出的值
IPC_RMID:删除消息队列
三 实验
msg1.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h> #include <sys/msg.h> struct my_msg_st{
long int my_msg_type;
char some_text[BUFSIZ];
}; int main(){
int running=1;
int msgid;
struct my_msg_st some_data;
long int msg_to_receive=0;
//首先建立消息队列
msgid=msgget((key_t)1234,0666 | IPC_CREAT);
if(msgid==-1){
fprintf(stderr,"msgget failed with error:%d\n",errno);
exit(EXIT_FAILURE);
}
//从队列中获取消息,直到遇见end消息为止,最后删除队列
while(running){
if(msgrcv(msgid,(void *)&some_data,BUFSIZ,msg_to_receive,0)==-1){
fprintf(stderr,"msgrcv failed with error:%d\n",errno);
exit(EXIT_FAILURE);
}
printf("You wrote:%s",some_data.some_text);
if(strncmp(some_data.some_text,"end",3)==0){
running=0;
}
}
if(msgctl(msgid,IPC_RMID,0)==-1){
fprintf(stderr,"msgctl(IPC_RMID) failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
msg2.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h> #include <sys/msg.h>
#define MAX_TEXT 512 struct my_msg_st{
long int my_msg_type;
char some_text[MAX_TEXT];
}; int main(){
int running=;
struct my_msg_st some_data;
int msgid;
char buffer[BUFSIZ]; msgid=msgget((key_t),|IPC_CREAT);
if(msgid==-){
fprintf(stderr,"msgget failed with error:%d",errno);
exit(EXIT_FAILURE);
}
while(running){
printf("Enter some text:");
fgets(buffer,BUFSIZ,stdin);
some_data.my_msg_type=;
strcpy(some_data.some_text,buffer); if(msgsnd(msgid,(void *)&some_data,MAX_TEXT,)==-){
fprintf(stderr,"msgsnd failed\n");
exit(EXIT_FAILURE);
}
if(strncmp(buffer,"end",)==){
running=;
}
}
exit(EXIT_FAILURE);
}
Linux学习笔记28——消息队列的更多相关文章
- Linux进程间通信IPC学习笔记之消息队列(SVR4)
Linux进程间通信IPC学习笔记之消息队列(SVR4)
- Linux进程间通信IPC学习笔记之消息队列(Posix)
基础知识: 消息队列可认为是一个消息链表,有足够写权限的线程可往队列中放置消息,有足够读权限的线程可以从队列中取走消息.在某个进程往一人队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达. ...
- Redis学习笔记~实现消息队列比MSMQ更方便
什么是队列:简单的说就是数据存储到一个空间里(可以是内存,也可以是物理文件),先存储的数据对象,先被取出来,这与堆栈正好相反,消息队列也是这样,将可能出现高并发的数据进行队列存储,并按着入队的顺序依次 ...
- PetShop 4.0学习笔记:消息队列MSMQ
直到今天才知道,在我们每天都在用的Window系统里还有这么好用的一个编程组件:消息队列.它能够解决在大数据量交换的情况下的性能问题,特别是BS系统的数据库性能.而且它的异步处理方式能给程序员最大的便 ...
- Spring学习笔记3——消息队列(rabbitmq), 发送邮件
本节的内容是用户注册时,将邮箱地址先存入rabbitmq队列,之后返回给用户注册成功:之后消息队列的接收者从队列中获取消息,发送邮件给用户. 一.RabbitMQ介绍 如果之前对rabbitm ...
- Linux 学习笔记
Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...
- Linux学习笔记(一)2015.4.13
研究生由单片机转Linux学习 首先安装VMware虚拟机,用的是VMware 10.0 在VMware 10.0上安装视频上推荐的Red Hat Linux 5 安装后正式进入Linux学习 笔记1 ...
- Linux 学习笔记之超详细基础linux命令 Part 1
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 说明:主要是在REHL Server 6操作系统下进行的测试 --字符界面虚拟终端与图形界面之间的切 方法:[ ...
- Intel® Media SDK Media Samples Linux 学习笔记(转)
最近折腾intel media sdk,主要硬件平台是在HD4600的核显上进行测试,intel media sdk是intel提供的一种基于核显的硬件编解码的解决方案,之前已经有使用ffmpeg进行 ...
随机推荐
- PGsql解决时差24H
SELECT sa_ed_time, sa_st_time, case when sa_ed_time > sa_st_time then extract(EPOCH FROM (sa_ed_t ...
- 网站集A的子网站B上没有解决方案C发布的webpart
在A的主站点,查看解决方案C在该网站集的feature,若未打开,则打开:若已经打开,可以先关闭再打开一次. 如果问题依然存在,可以查看子网站B上的feature是否打开,若未打开,则打开:若已经打开 ...
- [上传下载] C#FileUp文件上传类 (转载)
点击下载 FileUp.zip 主要功能如下 .把上传的文件转换为字节数组 .流转化为字节数组 .上传文件根据FileUpload控件上传 .把Byte流上传到指定目录并保存为文件 看下面代码吧 // ...
- viewpager在最后一页滑动之后,跳转到主页面
[TOC] viewpager在最后一页滑动之后,跳转到主页面 思路 主要有是两个监听, 一是addOnPageChangeListener();二是setOnTouchListener(): add ...
- 自己写的SqlHelper
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using ...
- Java RMI 框架_远程方法调用(2016-08-16)
概念: Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可 ...
- 利用CART算法建立分类回归树
常见的一种决策树算法是ID3,ID3的做法是每次选择当前最佳的特征来分割数据,并按照该特征所有可能取值来切分,也就是说,如果一个特征有四种取值,那么数据将被切分成4份,一旦按某特征切分后,该特征在之后 ...
- canvas之----浮动小球
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- TCP与UDP网络编程总结(一)
(1):TCP网络编程 我们注意到服务端与客户端通信时是通过客户端的套接字相互通信的,那么服务端的套接字主要是干什么用的呢? TCP服务端设置监听套接字时 int listen(int sock,in ...
- 单页应用引擎的写法artTemplate
使用到了ba-haschange.js <script src="../style/js/plugin/template-native-debug.js"></s ...