当前位置: 首页 > news >正文

制定网站建设方案厦门网

制定网站建设方案,厦门网,深圳影视广告公司,厦门网络营销顾问前言 开发设计时,通常会对业务流程进行模块化,有些流程之间,不要求同步,但又需要传递信息时,如果存储到数据库,效率降低很多,如果是存放在内存是最好的。此时可以选择系统的IPC(进程…

前言

        开发设计时,通常会对业务流程进行模块化,有些流程之间,不要求同步,但又需要传递信息时,如果存储到数据库,效率降低很多,如果是存放在内存是最好的。此时可以选择系统的IPC(进程间通信,如共享内存等),本文讲解的是适合轻量级的队列缓存场景的mqueue。

功能讲解

mqueue特性

        Linux的mqueue(消息队列)是POSIX标准中定义的进程间通信(IPC)机制,允许不同进程通过内核维护的队列传递结构化消息。其具备以下几个特性:

  • 存储在指定文件:mqueue消息队列文件默认挂载在/dev/mqueue目录下。通过mq_open创建的消息队列会在此目录生成对应文件节点,内核使用红黑树管理消息的存储与优先级
  • 持久性:POSIX消息队列随系统重启消失
  • 可在命令行查看队列信息:cat /dev/mqueue/[队列名]  # 查看队列属性(如最大消息数、消息大小)

功能介绍

需求场景:某些功能需要在root用户下作为服务执行,组装的生产数据需要推送给登录系统桌面的普通用户权限的应用。

下面以在root权限下运行的读取usb信息的服务,监测USB的插拔事件并把信息推送到mqueue,而普通用户的应用通过读取mqueue获取USB插拔信息为例。

获取事件信息写入mqueue

#ifndef USBACTION_H_
#define USBACTION_H_
#include <unistd.h>
#include <cstring>
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>#include <cstdio>
#include <stdio.h>
#include <dlfcn.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <libudev.h>
#include <mqueue.h>
using namespace std;
#define MAX_NUM 100struct Message {long mtype; // 消息类型char mtext[256]; // 消息内容
};const int MSG_TYPE = 1;
const char* QUEUE_NAME = "/usb_msg";//在/dev/mqueue目录下class Usbaction: public TUtilBase {
public:Usbaction();~Usbaction();int Run();private://int Init();//初始化void monitorDevices();int sendtomqueue(const char* mqstr);unsigned int uSleepTime;                //刷新间隔};#endif /* USBACTION_H_ */
#include "usbaction.h"std::vector<std::string> split(const std::string& str, char delimiter) {std::vector<std::string> tokens;std::istringstream tokenStream(str);std::string token;while (std::getline(tokenStream, token, delimiter)) {tokens.push_back(token);}return tokens;
}Usbaction::Usbaction() {uSleepTime = 5;
}Usbaction::~Usbaction() {
}int Usbaction::sendtomqueue(const char* mqstr){mqd_t mq;struct mq_attr attr;attr.mq_flags = O_NONBLOCK;  // 设置为非阻塞模式attr.mq_maxmsg = MAX_NUM;	 // 队列中最大消息数attr.mq_msgsize = sizeof(Message);// 消息的最大大小(字节)attr.mq_curmsgs = 0;         // 队列中当前消息数mq = mq_open(QUEUE_NAME, O_CREAT | O_WRONLY, 0644, &attr);if (mq == (mqd_t)-1) {WRITELOG(LOG_ERROR,"mq_open Error");return 0;}Message msg;msg.mtype = MSG_TYPE;strcpy(msg.mtext,mqstr);//attr.mq_flags |= O_NONBLOCK;if (mq_setattr(mq, &attr, NULL) == -1) {return 0;}if (mq_send(mq, reinterpret_cast<char*>(&msg), sizeof(msg), 0) == -1) {if (errno == EAGAIN) {} else {perror("mq_send");}}else {std::cout << "Message sent: " << msg.mtext << std::endl;}// 关闭消息队列mq_close(mq);return 1;
}void Usbaction::monitorDevices() {// 创建 udev 对象struct udev *udev = udev_new();if (!udev) {return;}// 创建 udev 监视器struct udev_monitor *mon = udev_monitor_new_from_netlink(udev, "udev");if (!mon) {udev_unref(udev);return;}// 添加过滤器以匹配usb 子系统udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", nullptr);udev_monitor_enable_receiving(mon);std::cout << "Monitoring block and USB events. Press Ctrl+C to exit." << std::endl;while (true) {struct udev_device *dev = udev_monitor_receive_device(mon);if (dev) {bool bfind=false;std::string level="";const char* subsystem = udev_device_get_subsystem(dev);const char* action = udev_device_get_action(dev);const char* devnode = udev_device_get_devnode(dev);const char *pro = udev_device_get_property_value(dev, "ID_USB_INTERFACES");if (subsystem && action && devnode) {if (strcmp(action,"add")==0||strcmp(action,"remove")==0){bfind=true;std::vector<std::string> tokens = split(devnode, '/');// 确保有至少两个分割结果if (tokens.size() >= 2) {string device = tokens[tokens.size() - 1];string bus = tokens[tokens.size() - 2];level = bus + ":" + device;}}}if (bfind) {const char* idVendor = udev_device_get_sysattr_value(dev,"idVendor");const char* idProduct = udev_device_get_sysattr_value(dev, "idProduct");if (idVendor && idProduct) {//strcmp(action,"add")==0char sendbuf[256]={0};if(pro){sprintf(sendbuf,"%s,%s,%s:%s,%s",action,level.c_str(),idVendor,idProduct,pro);}elsesprintf(sendbuf,"%s,%s,%s:%s",action,level.c_str(),idVendor,idProduct);sendtomqueue(sendbuf);
%s",action,level.c_str(),idVendor,idProduct);}else{char sendbuf[256]={0};sprintf(sendbuf,"%s,%s",action,level.c_str());sendtomqueue(sendbuf);}}udev_device_unref(dev);}usleep(500000); // Sleep for 0.5 seconds}udev_monitor_unref(mon);udev_unref(udev);
}int Usbaction::Init() {//logif (0== BInit(APP_TYPE_LOG, ACTIVITYCENSUS_LOG, 0)) {return 0;}return 1;
}int Usbaction::Run() {//初始化if (NS_FAILED == Init()) {return 0;}monitorDevices();return 1;
}int main(int argc, char **argv) {Usbaction action;action.Run();return 0;}

makefile

CC        = g++
CFLAGS    =
DEBUGFLAG = -g -Wall
MACRO     =
#MACRO     = -D_DEBUG 
LIBDIRS   = 
LIBS      = -ldl -ludev -lrt
INCLUDE   = 
MAKE_SO   = 
OPTIONS   = 
OBJDIR    =
SRCDIR    =
RUNOUTPUT = usbaction
LIBOUTPUT =
OBJS      = usbaction.odefault:$(RUNOUTPUT)clean:rm -f $(OBJS) $(RUNOUTPUT)install:cp -f $(RUNOUTPUT) ../../bin$(RUNOUTPUT):$(OBJS)$(CC)   -o $(RUNOUTPUT) $^ $(OPTIONS)  $(LIBDIRS) $(LIBS).cpp.o:$(CC) $(DEBUGFLAG) $(MACRO) -fPIC -c $< -o $@ $(CFLAGS) $(INCLUDE)

读取mqueue

普通应用权限的应用可以读取root用户权限的mqueue文件,下面是非阻塞式读取队列数据。

#include <iostream>
#include <mqueue.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <cstring>
#include <unistd.h>struct Message {long mtype;        // 消息类型char mtext[256];   // 消息内容
};const char* QUEUE_NAME = "/ymore_msg"; // 消息队列的名称int main() {// 打开消息队列以读取模式mqd_t mq = mq_open(QUEUE_NAME, O_RDONLY | O_NONBLOCK);if (mq == (mqd_t)-1) {std::cerr << "Error opening message queue: " << strerror(errno) << std::endl;return 1;}Message msg;ssize_t bytes_read;// 循环接收消息while (true) {bytes_read = mq_receive(mq, reinterpret_cast<char*>(&msg), sizeof(msg), NULL);if (bytes_read == -1) {std::cerr << "Error receiving message: " << strerror(errno) << std::endl;break;}std::cout << "Received message: " << msg.mtext << std::endl;// 如果读取到队列为空,可以根据条件退出// 例如,使用 `mq_getattr()` 获取队列的当前状态struct mq_attr attr;if (mq_getattr(mq, &attr) == -1) {std::cerr << "Error getting queue attributes: " << strerror(errno) << std::endl;break;}// 如果队列中没有消息,退出循环if (attr.mq_curmsgs == 0) {std::cout << "No more messages in the queue." << std::endl;break;}}// 关闭消息队列mq_close(mq);return 0;
}

结尾

        Linux后台C/C++项目,一般在架构设计时,可以设计共享内容来内部处理缓存数据,但也有考虑到第三方应用或者扩展型应用的场景,此时mqueue是比较合适了,如果是高并发的队列缓存,还是得找成熟的队列缓存中间件,比如kafka。

http://www.khdw.cn/news/52370.html

相关文章:

  • wordpress 不同站点推广产品引流的最佳方法
  • 网上有做任务赚钱的网站株洲网站建设
  • wordpress订单管理插件长沙seo优化首选
  • 合肥做百度网站天津百度分公司
  • 成都网站搭建公司百度下载软件
  • 国内用JSP做的网站有哪些青岛seo杭州厂商
  • wordpress自定义登录页深圳seo优化公司
  • 自己做网站 有名6百度seo报价
  • 做细分行业信息网站线上推广的方法
  • 做期货在哪个网站查资料安徽seo网络推广
  • 三亚河北建设招聘信息网站游戏推广文案
  • 横沥做网站兰州怎么提高网站的排名
  • 网页界面设计教材玉溪seo
  • dz网站如何搬家深圳全网推广公司
  • 网站建设按什么收费整站优化和单词
  • 会展设计制作优化方案的格式及范文
  • 圣辉友联做网站公司长岭网站优化公司
  • 网站制作服务订单济南seo优化公司
  • 做网站建设的公司有哪些sem是什么电镜
  • 俄语网站都哪些抖音关键词搜索排名收费
  • 网站优化毕业设计外贸营销网站
  • 做网站推广怎么做网页制作成品
  • java下的wordpress大连seo建站
  • 南充做网站厦门seo怎么做
  • 在线做venn图网站种子搜索神器网页版
  • 网站关键词优化服务海外品牌推广
  • 网站的关键词在哪里设置青岛网络推广公司排名
  • 寻找郑州网站建设公司海外推广专员
  • 西安房产网签查询系统南宁网站seo外包
  • 柳州电商网站建设免费留电话的广告