一 关于消息队列

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

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

二 相关函数

#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. Asp.net Mvc对比Php的4大误解

    一:asp.net技术已过时,Php技术更新 Asp.net mvc 5 发布于2014 夏天. 二:php开发者更多,所以更能得到帮助 2者对比犹如下图,会拿电锯的肯定多少会点锯子, 会用锯子的不一 ...

  2. MVC中HttpContext, HttpContextBase, HttpContextWrapper联系

    HttpContext // // 摘要: // 封装有关个别 HTTP 请求的所有 HTTP 特定的信息. public sealed class HttpContext : IServicePro ...

  3. javascript-设置div隐藏

    html code: <div class="title"> <ul id="col02_left_title"> <li> ...

  4. IIS防止同一IP大量非法访问

    在服务器设置访问规则,屏蔽恶意ip就可以了

  5. JavaScript中的作用域和闭包

    首先强烈安利<你不知道的JavaScript>,JS初学者进阶必读. 对于从C++.Java等静态语言转向JavaScript的初学者(比如我)来说,JS一些与众不同而又十分要紧的特性使得 ...

  6. a-b(高精度)

    我现在已经是才语言中的一员了,我在此献上今日的佳作——a-b(高精度),以下是我的程序及其注释,欢迎各位来观赏,耶! 程序: #include<stdio.h> #include<s ...

  7. Java面向对象程序设计--接口和内部类

    1.接口的定义: In the Java programming language, an interface is not a class but          staff[0] =       ...

  8. 说说http请求

    为什么做web前端要了解http标准?因为浏览器要从服务端获取网页,网页也可能将信息再提交给服务器,这其中都有http的连接.web系统既然和http链接有瓜葛,你就必须去了解它.我将从一下几个方面讲 ...

  9. 开启 htaccess 配置

    是在wamp中,apache2.2 开启 伪静态时,httpd.conf 配置如下: 查找 <Directory />Options FollowSymLinksAllowOverride ...

  10. configure: error: Cannot find libmysqlclient under /usr Note that the MySQL client library is not bundled anymore! 报错解决

    错误说明 今天在centos 6.3 64位版本上安装PHP5.4.3时在./configure 步骤的时候出现了下面错误configure: error: Cannot find libmysqlc ...