什么是消息队列?在Linux中使用消息队列

下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处。有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信——使用命名管道 一、什么是消息队列消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。 Linux用宏MSGMAX和MSGMNB来限制一条消息的最大长度和一个队列的最大长度。 二、在Linux中使用消息队列Linux提供了一系列消息队列的函数接口来让我们方便地使用它来实现进程间的通信。它的用法与其他两个System V PIC机制,即信号量和共享内存相似。 1、msgget函数该函数用来创建和访问一个消息队列。它的原型为:[cpp] view plain copy  print?

int msgget(key_t, key, int msgflg);  

与其他的IPC机制一样,程序必须提供一个键来命名某个特定的消息队列。msgflg是一个权限标志,表示消息队列的访问权限,它与文件的访问权限一样。msgflg可以与IPC_CREAT做或操作,表示当key所命名的消息队列不存在时创建一个消息队列,如果key所命名的消息队列存在时,IPC_CREAT标志会被忽略,而只返回一个标识符。 它返回一个以key命名的消息队列的标识符(非零整数),失败时返回-1. 2、msgsnd函数该函数用来把消息添加到消息队列中。它的原型为:[cpp] view plain copy  print?

int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);  

msgid是由msgget函数返回的消息队列标识符。 msg_ptr是一个指向准备发送消息的指针,但是消息的数据结构却有一定的要求,指针msg_ptr所指向的消息结构一定要是以一个长整型成员变量开始的结构体,接收函数将用这个成员来确定消息的类型。所以消息结构要定义成这样: [cpp] view plain copy  print?

struct my_message{  

    long int message_type;  

    /* The data you wish to transfer*/  

};  

msg_sz是msg_ptr指向的消息的长度,注意是消息的长度,而不是整个结构体的长度,也就是说msg_sz是不包括长整型消息类型成员变量的长度。 msgflg用于控制当前消息队列满或队列消息到达系统范围的限制时将要发生的事情。 如果调用成功,消息数据的一分副本将被放到消息队列中,并返回0,失败时返回-1. 3、msgrcv函数该函数用来从一个消息队列获取消息,它的原型为[cpp] view plain copy  print?

int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);  

msgid, msg_ptr, msg_st的作用也函数msgsnd函数的一样。 msgtype可以实现一种简单的接收优先级。如果msgtype为0,就获取队列中的第一个消息。如果它的值大于零,将获取具有相同消息类型的第一个信息。如果它小于零,就获取类型等于或小于msgtype的绝对值的第一个消息。 msgflg用于控制当队列中没有相应类型的消息可以接收时将发生的事情。 调用成功时,该函数返回放到接收缓存区中的字节数,消息被复制到由msg_ptr指向的用户分配的缓存区中,然后删除消息队列中的对应消息。失败时返回-1. 4、msgctl函数该函数用来控制消息队列,它与共享内存的shmctl函数相似,它的原型为:[cpp] view plain copy  print?

int msgctl(int msgid, int command, struct msgid_ds *buf);  

command是将要采取的动作,它可以取3个值,    IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。    IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值    IPC_RMID:删除消息队列 buf是指向msgid_ds结构的指针,它指向消息队列模式和访问权限的结构。msgid_ds结构至少包括以下成员: [cpp] view plain copy  print?

struct msgid_ds  

{  

    uid_t shm_perm.uid;  

    uid_t shm_perm.gid;  

    mode_t shm_perm.mode;  

};  

成功时返回0,失败时返回-1. 三、使用消息队列进行进程间通信马不停蹄,介绍完消息队列的定义和可使用的接口之后,我们来看看它是怎么让进程进行通信的。由于可以让不相关的进程进行行通信,所以我们在这里将会编写两个程序,msgreceive和msgsned来表示接收和发送信息。根据正常的情况,我们允许两个程序都可以创建消息,但只有接收者在接收完最后一个消息之后,它才把它删除。 接收信息的程序源文件为msgreceive.c的源代码为: [cpp] view plain copy  print?

#include   

#include   

#include   

#include   

#include   

#include   

struct msg_st  

{  

    long int msg_type;  

    char text[BUFSIZ];  

};  

int main()  

{  

    int running = 1;  

    int msgid = -1;  

    struct msg_st data;  

    long int msgtype = 0; //注意1  

    //建立消息队列  

    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  

    if(msgid == -1)  

    {  

        fprintf(stderr, “msgget failed with error: %dn”, errno);  

        exit(EXIT_FAILURE);  

    }  

    //从队列中获取消息,直到遇到end消息为止  

    while(running)  

    {  

        if(msgrcv(msgid, (void*)&data, BUFSIZ, msgtype, 0) == -1)  

        {  

            fprintf(stderr, “msgrcv failed with errno: %dn”, errno);  

            exit(EXIT_FAILURE);  

        }  

        printf(“You wrote: %sn”,data.text);  

        //遇到end结束  

        if(strncmp(data.text, “end”, 3) == 0)  

            running = 0;  

    }  

    //删除消息队列  

    if(msgctl(msgid, IPC_RMID, 0) == -1)  

    {  

        fprintf(stderr, “msgctl(IPC_RMID) failedn”);  

        exit(EXIT_FAILURE);  

    }  

    exit(EXIT_SUCCESS);  

}  

发送信息的程序的源文件msgsend.c的源代码为: [cpp] view plain copy  print?

#include   

#include   

#include   

#include   

#include   

#include   

#define MAX_TEXT 512  

struct msg_st  

{  

    long int msg_type;  

    char text[MAX_TEXT];  

};  

int main()  

{  

    int running = 1;  

    struct msg_st data;  

    char buffer[BUFSIZ];  

    int msgid = -1;  

    //建立消息队列  

    msgid = msgget((key_t)1234, 0666 | IPC_CREAT);  

    if(msgid == -1)  

    {  

        fprintf(stderr, “msgget failed with error: %dn”, errno);  

        exit(EXIT_FAILURE);  

    }  

    //向消息队列中写消息,直到写入end  

    while(running)  

    {  

        //输入数据  

        printf(“Enter some text: “);  

        fgets(buffer, BUFSIZ, stdin);  

        data.msg_type = 1;    //注意2  

        strcpy(data.text, buffer);  

        //向队列发送数据  

        if(msgsnd(msgid, (void*)&data, MAX_TEXT, 0) == -1)  

        {  

            fprintf(stderr, “msgsnd failedn”);  

            exit(EXIT_FAILURE);  

        }  

        //输入end结束输入  

        if(strncmp(buffer, “end”, 3) == 0)  

            running = 0;  

        sleep(1);  

    }  

    exit(EXIT_SUCCESS);  

}  

运行结果如下:什么是消息队列?在Linux中使用消息队列 什么是消息队列?在Linux中使用消息队列 四、例子分析——消息类型 这里主要说明一下消息类型是怎么一回事,注意msgreceive.c文件main函数中定义的变量msgtype(注释为注意1),它作为msgrcv函数的接收信息类型参数的值,其值为0,表示获取队列中第一个可用的消息。再来看看msgsend.c文件中while循环中的语句data.msg_type = 1(注释为注意2),它用来设置发送的信息的信息类型,即其发送的信息的类型为1。所以程序msgreceive能够接收到程序msgsend发送的信息。 如果把注意1,即msgreceive.c文件main函数中的语句由long int msgtype = 0;改变为long int msgtype = 2;会发生什么情况,msgreceive将不能接收到程序msgsend发送的信息。因为在调用msgrcv函数时,如果msgtype(第四个参数)大于零,则将只获取具有相同消息类型的第一个消息,修改后获取的消息类型为2,而msgsend发送的消息类型为1,所以不能被msgreceive程序接收。重新编译msgreceive.c文件并再次执行,其结果如下: 什么是消息队列?在Linux中使用消息队列
我们可以看到,msgreceive并没有接收到信息和输出,而且当msgsend输入end结束后,msgreceive也没有结束,通过jobs命令我们可以看到它还在后台运行着。 五、消息队列与命名管道的比较 消息队列跟命名管道有不少的相同之处,通过与命名管道一样,消息队列进行通信的进程可以是不相关的进程,同时它们都是通过发送和接收的方式来传递数据的。在命名管道中,发送数据用write,接收数据用read,则在消息队列中,发送数据用msgsnd,接收数据用msgrcv。而且它们对每个数据都有一个最大长度的限制。 与命名管道相比,消息队列的优势在于,1、消息队列也可以独立于发送和接收进程而存在,从而消除了在同步命名管道的打开和关闭时可能产生的困难。2、同时通过发送消息还可以避免命名管道的同步和阻塞问题,不需要由进程自己来提供同步方法。3、接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。

以上就是什么是消息队列?在Linux中使用消息队列的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/189223.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月1日 12:24:18
下一篇 2025年11月1日 12:26:09

相关推荐

  • 如何在 VS Code 中解决折叠代码复制问题?

    解决 VS Code 折叠代码复制问题 在 VS Code 中使用折叠功能可以帮助组织长代码,但使用复制功能时,可能会遇到只复制可见部分的问题。以下是如何解决此问题: 当代码被折叠时,可以使用以下简单操作复制整个折叠代码: 按下 Ctrl + C (Windows/Linux) 或 Cmd + C …

    2025年12月24日
    000
  • 姜戈顺风

    本教程演示如何在新项目中从头开始配置 django 和 tailwindcss。 django 设置 创建一个名为 .venv 的新虚拟环境。 # windows$ python -m venv .venv$ .venvscriptsactivate.ps1(.venv) $# macos/linu…

    2025年12月24日
    000
  • css中hover怎么使用

    CSS中的hover伪类是一个非常常用的选择器,它允许我们在鼠标悬停在元素上时改变其样式。本文将为大家介绍hover的用法,并提供具体的代码示例。 一、基本用法要使用hover,我们需要先为该元素定义一个样式,然后使用:hover伪类来制定鼠标悬停时对应的样式。例如,我们有一个button元素,当鼠…

    2025年12月24日
    000
  • 优先选择绝对定位的情况是什么?

    什么情况下应该优先考虑使用绝对定位? 绝对定位是CSS中一种重要的定位方式,它可以让一个元素相对于其最近的已定位的祖先元素进行绝对定位。在某些情况下,绝对定位可以提供更灵活,更精确的布局效果。本文将探讨在哪些情况下应该优先考虑使用绝对定位,并通过具体的代码示例来说明。 重叠元素的布局当页面中的元素需…

    2025年12月24日
    000
  • 如何使用Css Flex 弹性布局创建多列平铺效果

    如何使用CSS Flex弹性布局创建多列平铺效果 在Web开发中,我们经常会遇到需要创建多列平铺效果的情况,例如展示产品列表、照片墙等。传统的方法通常使用浮动布局或者设置固定宽度来实现,但是这些方法不够灵活,而且在适应性方面存在一定的问题。而CSS Flex弹性布局则提供了更加简单高效的解决方案。 …

    2025年12月24日
    000
  • css中属性值继承如何使用

    这次给大家带来css中属性值继承如何使用,使用css中属性值继承的注意事项有哪些,下面就是实战案例,一起来看一下。 继承:html元素可以从父元素那里继承一部分css属性,即使当前元素没有定义该属性。 1.css可以和不可以继承的属性 不可继承的:display、margin、border、padd…

    好文分享 2025年12月24日
    000
  • CSS的显示模式如何使用

    这次给大家带来css的显示模式如何使用,使用css的显示模式的注意事项有哪些,下面就是实战案例,一起来看一下。 一. 标签补充  div 和s pan 1.什么是div? 作用: 一般用于配合css完成网页的基本布局 2.什么是span? 作用: 一般用于配合css修改网页中的一些局部信息 3.di…

    好文分享 2025年12月24日
    000
  • css的hack技术使用汇总

    什么是css hack? 在web开发中,我们经常会遇到各浏览器表现不一致的情况,由于不同厂商的流览器或某浏览器的不同版本,对CSS的支持、解析不一样,导致在不同浏览器的环境中呈现出不一致的页面展现效果。这时,我们为了获得统一的页面效果,就需要针对不同的浏览器或不同版本写特定的CSS样式,我们把这个…

    好文分享 2025年12月23日
    000
  • 关于CSS3中选择符的实例详解

    英文原文: www.456bereastreet.com/archive/200601/css_3_selectors_explained/中文翻译: www.dudo.org/article.asp?id=197注:本文写于2006年1月,当时IE7、IE8和Firefox3还未发行,文中所有说的…

    好文分享 2025年12月23日
    000
  • 如何查看编写的html_查看自己编写的HTML文件效果【效果】

    要查看HTML文件的浏览器渲染效果,需确保文件以.html为扩展名保存、用浏览器直接打开、利用开发者工具调试、必要时启用本地HTTP服务器、或使用编辑器实时预览插件。 如果您编写了HTML代码,但无法直观看到其在浏览器中的实际渲染效果,则可能是由于文件未正确保存、未使用浏览器打开或文件扩展名设置错误…

    2025年12月23日
    400
  • html5怎么设置黑体_html5用CSS font-family设黑体或font-weight加粗【设置】

    在HTML5中实现黑体及加粗需用CSS的font-family和font-weight:一、font-family按优先级列“SimHei”,“Microsoft YaHei”,“Heiti SC”,sans-serif;二、font-weight用700或bold;三、组合声明并注意继承;四、可用…

    2025年12月23日
    000
  • navigator怎么用html5_HTML5用navigator对象查浏览器信息如语言【对象】

    可通过navigator对象获取浏览器语言、设备类型、平台信息、地理定位和媒体设备支持:navigator.language/languages返回语言代码;userAgent判断移动设备;platform返回操作系统;geolocation检测定位支持;mediaDevices检查媒体访问能力。 …

    2025年12月23日
    000
  • html5怎么找颜色_html5用取色器或CSS命名如red快速找对应颜色【查找】

    可通过浏览器开发者工具取色、CSS命名颜色对照表、在线十六进制颜色查找工具及CSS自定义属性验证四种方法快速定位颜色值对应的实际色彩效果。 如果您在HTML5开发中需要快速定位某个颜色值对应的实际色彩效果,可以通过取色器工具或CSS预定义颜色名称来识别。以下是查找颜色的具体操作方法: 一、使用浏览器…

    2025年12月23日
    000
  • html5如何清除缓存_HTML5缓存清除步骤与清理浏览器缓存方法【教程】

    HTML5网页应用异常通常由浏览器缓存旧资源导致,需依次清除常规缓存、强制刷新、清理AppCache、注销Service Worker并清空其缓存、或用无痕模式验证。 如果您在使用HTML5网页应用时遇到内容未更新、页面显示异常或资源加载错误等问题,可能是由于浏览器缓存了旧版本的HTML、CSS、J…

    2025年12月23日
    000
  • html5怎么快速输入_HTML5用编辑器代码片段或Emmet缩写快速生成【输入】

    可利用Emmet缩写、编辑器代码片段及内置HTML5模板快速生成标准结构:输入!+Tab生成HTML5骨架;自定义snippets如sect插入语义化section;WebStorm新建HTML5文件自动添加必需meta;启用Emmet插件支持header/nav等语义标签缩写。 如果您在编写HTM…

    2025年12月23日
    000
  • html如何上传到空间_将HTML文件上传到网站空间步骤【步骤】

    HTML文件无法上网访问是因为未上传至网站空间,需通过FTP客户端、主机控制面板、Git部署或SFTP命令行四种方式之一上传到服务器根目录。 如果您已经编写完成一个HTML文件,但无法在互联网上访问它,则可能是由于该文件尚未上传至网站空间。以下是将HTML文件上传到网站空间的具体步骤: 一、使用FT…

    2025年12月23日
    300
  • 手机html5怎么编辑_手机用HTML编辑器写代码实时预览编辑HTML5内容【编辑】

    推荐Dcoder、Acode(配Live Server插件)、JSFiddle Mobile和Codeanywhere四款工具:Dcoder支持本地WebView预览;Acode通过Live Server实现热更新;JSFiddle提供三栏在线编辑与响应式预览;Codeanywhere依托云端容器支…

    2025年12月23日
    000
  • html如何看懂_看懂并理解HTML代码结构【理解】

    掌握HTML解析需五步:一、识别%ignore_a_1%根元素及head/body骨架;二、依缩进分析嵌套层级;三、辨识header、nav等语义标签功能;四、解析class、href等属性与文本关联;五、用浏览器开发者工具验证DOM结构。 如果您看到一段HTML代码但无法快速识别其组织方式和各标签…

    2025年12月23日
    200
  • HTML如何实现Debug调试_错误排查与修复方法【教程】

    应优先使用浏览器开发者工具排查:按F12或Cmd+Option+I打开,切换至Console面板查看红色错误信息,如Uncaught SyntaxError等。 如果您在编写或运行HTML页面时遇到显示异常、功能失效或控制台报错等问题,则可能是由于标签未闭合、属性拼写错误、JavaScript嵌入不…

    2025年12月23日
    000
  • putty怎么运行html_putty连接环境运行html方法【教程】

    1、可通过本地浏览器查看:使用SFTP下载HTML文件后双击用默认浏览器打开预览;2、启动轻量级Web服务器:在PuTTY中用Python命令python3 -m http.server 8000运行并本地访问服务器IP:8000查看;3、配置Apache:安装Apache2服务,将HTML文件放入…

    2025年12月23日
    000

发表回复

登录后才能评论
关注微信