一 关于消息队列

  消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法,而且,每个数据块都被认为含有一个类型,接收进程可以独立地接受含有不同类型值的数据块。可以通过发送消息来几乎完全避免命名管道的同步和阻塞问题。但是,与管道一样,每个数据块都有一个最大长度的限制,系统中所有队列所包含的全部数据块的总长度都有一个上限。

  与命名管道相比,消息队列的优势是,它独立于发送和接受进程而存在,这消除了在同步命名管道的打开和关闭时可能产生的一些困难。

二 相关函数

#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——消息队列的更多相关文章

  1. Linux进程间通信IPC学习笔记之消息队列(SVR4)

    Linux进程间通信IPC学习笔记之消息队列(SVR4)

  2. Linux进程间通信IPC学习笔记之消息队列(Posix)

    基础知识: 消息队列可认为是一个消息链表,有足够写权限的线程可往队列中放置消息,有足够读权限的线程可以从队列中取走消息.在某个进程往一人队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达. ...

  3. Redis学习笔记~实现消息队列比MSMQ更方便

    什么是队列:简单的说就是数据存储到一个空间里(可以是内存,也可以是物理文件),先存储的数据对象,先被取出来,这与堆栈正好相反,消息队列也是这样,将可能出现高并发的数据进行队列存储,并按着入队的顺序依次 ...

  4. PetShop 4.0学习笔记:消息队列MSMQ

    直到今天才知道,在我们每天都在用的Window系统里还有这么好用的一个编程组件:消息队列.它能够解决在大数据量交换的情况下的性能问题,特别是BS系统的数据库性能.而且它的异步处理方式能给程序员最大的便 ...

  5. Spring学习笔记3——消息队列(rabbitmq), 发送邮件

    本节的内容是用户注册时,将邮箱地址先存入rabbitmq队列,之后返回给用户注册成功:之后消息队列的接收者从队列中获取消息,发送邮件给用户. 一.RabbitMQ介绍     如果之前对rabbitm ...

  6. Linux 学习笔记

    Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...

  7. Linux学习笔记(一)2015.4.13

    研究生由单片机转Linux学习 首先安装VMware虚拟机,用的是VMware 10.0 在VMware 10.0上安装视频上推荐的Red Hat Linux 5 安装后正式进入Linux学习 笔记1 ...

  8. Linux 学习笔记之超详细基础linux命令 Part 1

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122   说明:主要是在REHL Server 6操作系统下进行的测试 --字符界面虚拟终端与图形界面之间的切 方法:[ ...

  9. Intel® Media SDK Media Samples Linux 学习笔记(转)

    最近折腾intel media sdk,主要硬件平台是在HD4600的核显上进行测试,intel media sdk是intel提供的一种基于核显的硬件编解码的解决方案,之前已经有使用ffmpeg进行 ...

随机推荐

  1. (转)Java爬虫,信息抓取的实现

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/23272657 今天公司有个需求,需要做一些指定网站查询后的数据的抓取,于是花了点 ...

  2. Python初学记录

    发音: 拍怂 语系:类C 特点: 1语句控制不用{}和(),而是强制用户空格或tab缩进.空格和tab数量不一定. 2解释性语言,不需要事先声明变量,即写即用. 3.list 列表可存放多种类型数据. ...

  3. AndroidStudio字体主题样式分享

    最近慢慢在从eclipse往AndroidStudio习惯,但总觉得AS的默认字体颜色看的不舒服,便花了些时间将字体颜色样式改成了和原来类似的.以下是效果图. 这里是下载地址http://downlo ...

  4. C#当中的多线程_任务并行库(上)

    复习: 第三章内容中我们提到了三种异步编程模型,这里简单复习一下,分别如下 1.APM(异步编程模式):形如Beginxxx,Endxxx. 2.EAP(基于事件的异步编程模式):这个我们在.net中 ...

  5. linux命令sed学习笔记

    sed其实就是两个主要的知识点,那就是“怎么选择”和“怎么操作”!

  6. new、delete用法(一)

    第一部分:new的使用: #define DEBUG_NEW new(THIS_FILE, __LINE__)解释 THIS_FILE:表示当前类所处的文件名: __LINE__:表示分配内存操作所在 ...

  7. PDF在xp或2003下正常在win7下乱码的问题

    1.先确定当前PDF文件需要字体(在PDF工具打开找到Font字体可以查看具体需要哪些字体). 2.网上下载或者在生成PDF的电脑上把老版本字体拷贝出来然后在win7下安装,当提示已经存在该字体时,直 ...

  8. Google HTML/CSS/JS代码风格指南

    JS版本参见:http://www.zhangxinxu.com/wordpress/2012/07/google-html-css-javascript-style-guides/ HTML/CSS ...

  9. 异步调用backgroudworker

    先看一个小例子:C#客户端打开一个控件,控件中加载了好多数据大约要用5秒中,如果我们直接打开控件,那么这个控件就要5秒中才能弹出来,当然这个时候用户已经把他Kill了.这个时候我们就需要先给用户把控件 ...

  10. 原生javascript操作class-元素查找-元素是否存在-添加class-移除class

    //判断元素是否有classfunction hasClass(ele, cls) { return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\ ...