当前位置: 首页 > 编程日记 > 正文

linux进程间通信:POSIX 消息队列 ----异步通信

在上一篇中linux进程间通信:POSIX 消息队列我们知道消息队列中在消息个数达到了队列所能承载的上限,就会发生消息的写阻塞。
阻塞式的通信影响系统效率,进程之间在通信收到阻塞时并不能去做其他事情,而是一直处于阻塞状态。

为了避免出现这样的低效问题,POSIX消息队列推出如下接口实现异步通信机制

  • 函数头文件#include <mqueue.h>
  • 函数使用:int mq_notify(mqd_t mqdes, const struct sigevent *sevp);
  • 函数功能:允许调用者注册或者注销一个异步信号,当进行消息传输的时候利用该信号可以执行异步操作
    具体如下:
    当一个空的消息队列接收到消息时给进程发送一个通知;
    当执行完相关处理,通知机制结束,可以重新调用mq_notify注册
  • 函数参数:
    mqdes: 消息队列的id
    sevp: 通知方式设置
    其中关于结构体sigevent描述如下
    struct sigevent {int          sigev_notify; /* Notification method 通知的方式*/ int          sigev_signo;  /* Notification signal 通知发送的信号*/union sigval sigev_value;  /* Data passed with notification */void       (*sigev_notify_function) (union sigval);/* Function used for threadnotification (SIGEV_THREAD) */void        *sigev_notify_attributes;/* Attributes for notification thread(SIGEV_THREAD) */pid_t        sigev_notify_thread_id;/* ID of thread to signal (SIGEV_THREAD_ID) */
    };
    
    sigev_notify 通知的方式如下几种:
    • SIGEV_NONE 有通知时什么也不做
    • SIGEV_SIGNAL 给进程发送一个信号来通知进程
    • SIGEV_THREAD/SIGEV_THREAD_ID

代码演示如下:
mq_notify.c 异步读

#include<stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mqueue.h>
#include <signal.h>
#include <string.h>mqd_t mq_id;
char buf[8192];
struct sigevent sigev;static void signal_handler(int signo) {ssize_t receive_len;//再次进行消息队列和异步通知方式注册的结构体进行绑定mq_notify(mq_id, &sigev);//尝试从mq_id中获取消息receive_len = mq_receive(mq_id, buf,8192, NULL);if (receive_len == -1) {printf("mq_receive failed \n");_exit(-1);}printf("read %ld bytes: %s\n",(long) receive_len, buf);return ;
}int main() {//创建消息队列mq_id = mq_open("/notify",O_RDONLY | O_CREAT, 0666, NULL);if (mq_id == -1) {printf("mq_open failed \n");_exit(-1);}//信号处理逻辑,注册SIGUSR1用户信号,并设置回调函数signal(SIGUSR1, signal_handler);sigev.sigev_notify = SIGEV_SIGNAL;sigev.sigev_signo = SIGUSR1;//将消息队列的id和注册的异步通信结构体进行绑定mq_notify(mq_id, &sigev);int count = 0;while(1) {printf("while loop %d \n", count ++);sleep(1);}mq_close(mq_id);return 0;
}

mq_snd.c同步写

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <mqueue.h>
#include <string.h>int main () {mqd_t mq_id;//打开创建好的消息队列mq_id = mq_open("/notify",O_WRONLY | O_CREAT, 0666, NULL);if (mq_id == -1) {printf("mq_open failed\n");	_exit(-1);}//持续向消息队列中每隔两秒写入数据while(1) {if (mq_send(mq_id, "hello world", sizeof("hello world"), 1) == -1) {printf("mq_send failed \n");_exit(-1);}printf("msg send success -----\n");sleep(2);}return 0;
}

编译以上两个文件:gcc mq_notify.c -o mq_notify -lrt gcc mq_snd.c -o send -lrt
输出如下:
在这里插入图片描述
我们可以看到异步读并不会受消息队列为空的影响,即使消息队列为空,异步读进程仍然继续处理自己的事情;当同步写进程运行的时候,异步读进程收到一个使用mq_id注册的信号,开始执行信号回调函数,函数执行完,异步读进程继续处理自己的事情,直到再次收到相同的信号从而再次执行回调函数中的读消息队列。

相关文章:

【转】Android设计中的.9.png

来源&#xff1a;http://isux.tencent.com/android-ui-9-png.html Android设计中的.9.png 注意&#xff1a;当使用9.png做TextView背景时&#xff0c;一定要设置内容区域&#xff08;底部和右侧&#xff09;&#xff0c;否则&#xff0c;文字显示不出来。 偶米伽 2013.08.20在A…

python创建scrapy_Python爬虫教程-31-创建 Scrapy 爬虫框架项目

首先说一下&#xff0c;本篇是在 Anaconda 环境下&#xff0c;所以如果没有安装 Anaconda 请先到官网下载安装Scrapy 爬虫框架项目的创建0.打开【cmd】1.进入你要使用的 Anaconda 环境1.环境名可以在【Pycharm】的【Settings】下【Project&#xff1a;】下找到2.使用命令&#…

KOAProgressBar

2019独角兽企业重金招聘Python工程师标准>>> KOAProgressBar 是 iOS 上的一个进度条控件&#xff0c;要求 iOS 5 支持 转载:http://www.adobex.com/ios/source/details/00000866.htm 转载于:https://my.oschina.net/u/868244/blog/106310

linux进程间通信:POSIX信号量

文章目录概念描述编程接口注意事项编程案例信号量基本接口使用案例信号量父子进程间通信信号量实现 两进程之间通信概念描述 英文&#xff1a;semaphore 简称SEM&#xff0c;主要用来进行进程间同步本质&#xff1a;内核维护的一个正整数&#xff0c;可对其进行各种/-操作分类…

指针小白:修改*p与p会对相应的地址的变量产生什么影响?各个变量指针的长度为多少?...

这两天敲代码碰到了一个这样的问题 代码如下&#xff1a; 1 #include <stdio.h>2 #include <stdlib.h>3 int main()4 {5 int num1 10;6 7 int* p&num1;8 *p 20;9 10 printf("%p\n", &num1); 11 printf("%d\…

MVC自带表单效验

废话不说&#xff0c;直接上代码&#xff0c;一看就明白 源地址&#xff1a;http://www.cnblogs.com/sixiangqimeng/p/3561313.html [StringLength(5,ErrorMessage "*长度小于5")][Required(ErrorMessage "*必填啊&#xff01;")][Required(ErrorMessage…

mysql求每个订单的平均价_MySQL – 选择所有客户和每个客户的总订单和总价值

SELECT a.ID,a.Name,COUNT(b.Customer) totalOrders,SUM(b.value) total_valueFROM Customers aLEFT JOIN Orders bON a.ID b.CustomerGROUP BY a.ID,a.Name要么SELECT a.ID,a.Name,COUNT(b.Customer) totalOrders,COALESCE(SUM(b.value), 0) total_valueFROM Customers aLEFT…

windows server 2008设置远程桌面连接最大数量

windows server 2008设置远程桌面连接最大数量 系统默认远程桌面连接的数量为1 打开控制面板---管理工具---远程桌面服务---远程桌面会话主机设置---把"限制每个用户只能进行一个会话"勾选去掉&#xff1b; 然后双击连接中的RDP-Tcp---网络适配器--最大连接数 修改为…

BZOJ1002 [FJOI2007]轮状病毒(最小生成树计数)

Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 7125 Solved: 3878[Submit][Status][Discuss]Description 轮状病毒有很多变种&#xff0c;所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的&#xff0c;2个原子之间的…

linux进程间通信:POSIX 共享内存

文章目录思维导图通信原理优势POSIX 共享内存 编程接口编程案例思维导图 之前学习过sysemV 的共享内存的实现及使用原理&#xff0c;参考linux进程间通信&#xff1a;system V 共享内存 POSIX 同样提供共享内存的接口&#xff0c;基本原理和system V的共享内存是一样的。 通信…

求二进制中1的个数(编程之美2.1)

行文脉络 解法一——除法解法二——移位解法三——高效移位解法四——查表扩展问题——异或后转化为该问题对于一个字节&#xff08;8bit&#xff09;的变量&#xff0c;求其二进制“1”的个数。例如6&#xff08;二进制0000 0110&#xff09;“1”的个数为2&#xff0c;要求算…

mysql管理用户数据库_MySQL 数据库管理(一)(用户与受权)

前言在企业信息化的过程当中&#xff0c;数据库中库和表都会大量存在&#xff0c;须要分配给管理者核实的权限进行操做合理地分配权限&#xff0c;可使数据库管理井井有理&#xff0c;各个管理者只须要关注本身负责的内容&#xff0c;也可避免误操做对系统形成损失1、用户与受权…

Smart-linkmonitor-link配置注意事项

一、应用场合 Smart Link用于双上行组网&#xff0c;Monitor Link一般用于与Smart Link的联动&#xff0c;配置在Smart Link的上游设备。 二、注意事项 在配置过程中&#xff0c;请注意以下几点&#xff1a; ? 1、指定实例之前请先配置MSTP实例。MSTP的实例和VLAN映射关系发生…

封装OpenCL类

以上一篇《OpenCL入门测试》为基础&#xff0c;将函数封装到类中&#xff0c;方便调用。 #include <cstdlib> #include <iostream> #include <iomanip> #include <cstring> #include <cassert> #include <windows.h> #define CL_USE_DEPRE…

linux系统调用 ftruncate设置文件大小

系统调用ftruncate可以将一个文件裁剪为指定的大小&#xff0c;函数描述如下&#xff1a; 头文件&#xff1a;<unistd.h> <sys/types.h>函数使用&#xff1a; int truncate(const char *path, off_t length); int ftruncate(int fd, off_t length);函数参数&…

剑指 offer set 22 数组中的逆序数

总结 1. 题目为归并排序的变形, 不过我完全没想到 2. 在归并排序进行字符组 merge 时, 统计逆序数. merge 后, 两个子数组是有序的了, 下次再 merge 的时候就能以 o(n) 的时间内找到某一个逆序对第二个元素的个数 转载于:https://www.cnblogs.com/xinsheng/p/3564026.html

qt信号发送间隔短而槽耗时多_Qt信号槽问题汇总 - osc_9q1dp3jk的个人空间 - OSCHINA - 中文开源技术交流社区...

1. 发送一次信号&#xff0c;调用多次槽函数问题在同一个类中&#xff0c;多次链接QObject::connect(sender, SIGNAL(signalSender(QString, int)), receiver, SLOT(onSignalSender(QString, int))); 会导致发送一次信号signalSender(QString, int) 多次调用槽函数(onSignalSen…

一劳永逸关闭Windwos默认共享

对于IPC$&#xff0c;找到注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA下的RestrictAnonymous项&#xff0c;并将键值改为1。 对于其它默认共享&#xff0c;在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters下&#…

springboot 集成mybatis时日志输出

application.properties(yml)中配置的两种方式&#xff1a; 这两种方式的效果是一样的&#xff0c;但是下面一种可以指定某个包下的SQL打印出来&#xff0c;上面这个会全部的都会打印出来。 转载于:https://www.cnblogs.com/z0909y/p/10077565.html

linux文件IO与内存映射:用户空间的IO缓冲区

文章目录用户空间IO缓冲区产生IO缓冲区 描述IO缓冲区的写模式自定义IO缓冲区用户空间IO缓冲区产生 系统调用过程中会产生的开销如下&#xff1a; 切换CPU到内核态进行数据内容的拷贝&#xff0c;从用户态到内核态或者从内核态到用户态切换CPU到用户态 以上为普通到系统调用过…

java zookeeper_Java zookeeper开发实例

1、安装zookeeper下载zk http://archive.cloudera.com/cdh5/cdh/5/配置文件tickTime2000initLimit10syncLimit5# zk数据保存目录dataDir/usr/local/zookeeper/dataclientPort2181启动&#xff1a;bin/zkServer.sh start客户端命令行链接&#xff1a;bin/zkCli.sh2、拷贝zookeep…

【转】Maven Jetty 插件的问题(css/js等目录死锁)的解决

Maven Jetty 插件的问题&#xff08;css/js等目录死锁&#xff0c;不能自动刷新&#xff09;的解决&#xff1a;1. 打开下面的目录&#xff1a;C:\Users\用户名\.m2\repository\org\eclipse\jetty\jetty-webapp\&#xff0c;在进入版本对应的子目录&#xff0c;例如8.1.3.v2012…

ORA-4031错误深入解析

报ORA-4031错误时&#xff0c;我们通常可以根据Oracle无法分配多少字节的内存&#xff0c;来判断共享池碎片的严重程度&#xff0c;以下是4031错误官方的解释&#xff1a;[oracleguoyj ~]$ oerr ORA 403104031, 00000, "unable to allocate %s bytes of shared memory (\&…

buffers与cached的区别

具体参考以下博文&#xff1a; 1、https://www.cnblogs.com/chenpingzhao/p/5161844.html 2、https://blog.csdn.net/heweimingming/article/details/52230293 3、http://www.cnblogs.com/zhoug2020/p/6336453.html 其中3有top命令的详解。转载于:https://www.cnblogs.com/jia…

linux文件IO与内存映射:分散/聚集IO技术(scatter-gather)

前言 根据上文我们学习到的用户空间的IO缓冲区&#xff0c;操作系统为了减少系统调用的次数&#xff0c;节省系统开销&#xff0c;提出了用户空间的IO缓冲区&#xff0c;即为用户空间的文件读写开辟一段可以利用setvbuf配置大小的内存空间来作为文件IO缓冲区。 描述 为了在以…

android jni 调用 java_Android与JNI(二) ---- Java调用C++ 动态调用

目录&#xff1a;1. 简介2. JNI 组件的入口函数3. 使用 registerNativeMethods 方法4. 测试5. JNI 帮助方法6. 参考资料1. 简介Android与JNI(一)已经简单介绍了如何在 android 环境下使用 JNI 了。但是遵循 JNI 开发的基本步骤似乎有点死板&#xff0c;而且得到的本地函数名太…

如何查找并干掉僵尸进程

查找命令&#xff1a;ps -A -o stat,pid,ppid,cmd | grep -e ^[Zz] 找到之后 kill掉&#xff0c;然后用top命令查看是否kill成功&#xff0c;如果失败&#xff0c;kill 父进程。 转载于:https://www.cnblogs.com/kfx2007/p/3572249.html

[转] WINCC教学视频

原文地址http://www.ad.siemens.com.cn/club/bbs/post.aspx?b_id5&a_id1049763&s_id17&num0#anch WinCC 变量归档系列视频&#xff1a; http://www.ad.siemens.com.cn/service/elearning/cn/SerialVideo.aspx?vsid136 WinCC亚洲版高级工程师培训视频&#xff1a;…

UNL(Ubiquitous Navigation Lab)

转载于:https://www.cnblogs.com/Forwithy/p/10080078.html

linux 文件IO与内存映射:内存映射

前言 前面几篇我们学习了用户空间的IO缓冲区,以及IO缓冲区的分散聚合IO技术. 为了减少系统调用的次数&#xff0c;提升系统性能&#xff0c;操作系统开发者门提出了这么多的缓存技术。 但是到这里这些技术同样有不足的地方&#xff1a;不论是读或者写文件&#xff0c;都需要将…