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

SystemV-消息队列与责任链模式

一、SystemV 消息队列

1. 消息队列API

Ftok
  • 函数定义
    key_t ftok(const char *pathname, int proj_id);
  • 函数作用
    获取唯一的key值标识符,用于标识系统V消息队列。
  • 参数解释
    • pathname:有效的文件路径(需存在)。
    • proj_id:小于255的整数数字(通常为非零值)。
    • 返回值:唯一的key值,失败时返回-1
Msgget
  • 函数定义
    int msgget(key_t key, int msgflg);
  • 函数作用
    创建或获取内核消息队列,返回消息队列ID(文件描述符)。
  • 参数解释
    • key:由ftok函数返回的有效key值。
    • msgflg:标志位(常用宏组合):
      • IPC_CREATE:若队列不存在则创建,否则获取已有队列ID。
      • IPC_EXCL:需与IPC_CREATE联合使用,若队列存在则返回错误(避免重复创建)。
      • 权限模式(如0666):设置队列的访问权限。
相关指令
  • 查看内核消息队列
    ipcs -q  
    
  • 删除消息队列
    ipcrm -q <队列ID>  
    
  • 特性:消息队列是全双工的,支持双向通信。
Msgsnd(发送消息)
  • 函数定义
    int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
  • 自定义结构体
    struct msgbuf {  long mtype;       // 消息类型(正整数)  char mtext[N];   // 消息内容(自定义大小)  
    };  
    
  • 细节
    • msgp指向msgbuf结构体地址。
    • msgsz必须为sizeof(msgbuf.mtext)(仅计算内容部分,不含mtype)。
Msgrcv(接收消息)
  • 函数定义
    ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long mtype, int msgflg);
  • 细节:参数与msgsnd类似,通过mtype指定接收的消息类型(如0表示接收任意类型)。
Msgctl(控制消息队列)
  • 函数定义
    int msgctl(int msqid, int cmd, struct msqid_ds *buf);
  • 常用cmd参数
    • IPC_STAT:获取消息队列属性(存入buf)。
    • IPC_RMID:删除消息队列(立即标记为删除,后续无法访问)。

2. System-V 基本通信代码(C-S架构)

#pragma once  
#include <iostream>  
#include <unistd.h>  
#include <sys/types.h>  
#include <sys/ipc.h>  
#include <stdlib.h>  
#include <string.h>  
#include <sys/msg.h>  
#include "Log.hpp"  #define PATHNAME "./Queue"  
#define PROID 123  
#define CREATEMSGQUEUE (IPC_CREAT | IPC_EXCL | 0666)  
#define GETMSGQUEUE (IPC_CREAT)  enum {  SERVER_MSG_TYPE = 1,  CLIENT_MSG_TYPE  
} TYPE;  using namespace ns_log;  const int default_fd = -1;  
const int default_size = 1024; // 1k  class MsgQueue {  
private:  int _msgfd;  struct msgbuf {  long mtype;  char mtext[default_size];  };  public:  MsgQueue() : _msgfd(default_fd) {}  // 创建消息队列  void Create(int flag) {  key_t key = ::ftok(PATHNAME, PROID);  if (key == -1) {  LOG(FATAL, "ftok错误,error : %s\n", strerror(errno));  abort();  }  _msgfd = msgget(key, flag);  if (_msgfd == -1) {  LOG(FATAL, "创建消息队列失败\n");  abort();  }  LOG(DEBUG, "创建消息队列完毕\n");  }  // 发送消息  void Send(int type, const std::string &in) {  struct msgbuf buf;  memset(&buf, 0, sizeof(buf));  buf.mtype = type;  memcpy(buf.mtext, in.c_str(), in.size());  int n = msgsnd(_msgfd, &buf, sizeof(buf.mtext), 0);  if (n == -1) {  LOG(ERROR, "发送消息失败\n");  return;  }  LOG(DEBUG, "发送消息完毕\n");  }  // 读取数据  void Recv(int type, std::string *out) {  struct msgbuf buf;  int n = msgrcv(_msgfd, &buf, sizeof(buf.mtext), type, 0);  if (n == -1) {  LOG(ERROR, "接收消息错误\n");  return;  }  *out = std::string(buf.mtext, n);  }  
};  

二、责任链模式

1. 模式介绍

  • 定义:责任链模式是一种行为型设计模式,通过将请求处理对象连成一条链,使每个对象可以选择处理请求或传递给下一个对象,从而解耦请求的发送者与接收者。
  • 核心思想:请求沿链传递,直到被处理或链结束,每个节点可动态决定是否处理请求或转发。

2. 业务需求

  • 格式化消息:为接收的信息添加时间戳和进程PID。
  • 持久化保存:将消息保存到文件。
  • 文件分片:当文件过大时,按规则分片并保存到指定目录(Linux下重命名为原子操作)。

3. 编码实现

责任链基类
#pragma once  
#include <iostream>  
#include <string>  
#include <memory>  
#include <sstream>  
#include <fstream>  
#include <filesystem>  
#include <ctime>  
#include <unistd.h>  
#include <signal.h>  
#include <sys/types.h>  
#include <sys/wait.h>  const std::string default_filepath = "./log/";  
const std::string default_filename = "test.log";  
static std::string delfile;  // 责任链基类  
class Handler {  
public:  virtual ~Handler() {}  virtual void Execute(const std::string &text) = 0;  void SetNext(std::shared_ptr<Handler> next) { _next = next; }  void Enable() { _isEnable = true; }  void Disable() { _isEnable = false; }  protected:  std::shared_ptr<Handler> _next;  bool _isEnable = true;  // 获取当前时间(带PID)  virtual std::string GetCurrTime() {  time_t now_time = time(nullptr);  struct tm *curr_time = localtime(&now_time);  char buf[128];  snprintf(buf, sizeof(buf), "[%d-%02d-%02d %02d:%02d:%02d][%d]",  curr_time->tm_year + 1900, curr_time->tm_mon + 1,  curr_time->tm_mday, curr_time->tm_hour,  curr_time->tm_min, curr_time->tm_sec, getpid());  return buf;  }  
};  
格式化处理节点
// 格式化处理节点  
class HandlerFormatText : public Handler {  
public:  void Execute(const std::string &text) override {  std::string formattext = text;  if (_isEnable) {  std::stringstream ss;  ss << GetCurrTime() << text << "\n";  formattext = ss.str();  LOG(INFO, "格式化完毕,结果: %s\n", formattext.c_str());  }  if (_next) _next->Execute(formattext);  else LOG(DEBUG, "到达责任链结尾,本次任务处理完毕\n");  }  
};  
保存文件节点
// 保存文件节点  
class HandleSaveFile : public Handler {  
private:  std::string _filepath;  std::string _filename;  // 创建目录(若不存在)  void CreateFilepath() {  try {  std::filesystem::create_directories(_filepath);  } catch (std::filesystem::filesystem_error &error) {  LOG(ERROR, "创建⽬录%s失败\n", error.what());  }  }  public:  HandleSaveFile(const std::string &filepath = default_filepath,  const std::string &filename = default_filename)  : _filepath(filepath), _filename(filename) {  if (!std::filesystem::exists(_filepath)) CreateFilepath();  }  void Execute(const std::string &text) override {  std::string file = _filepath + _filename;  if (_isEnable) {  std::ofstream ofs(file, std::ios::app);  if (!ofs.is_open()) {  LOG(ERROR, "%s打开失败\n", file.c_str());  return;  }  ofs << text;  ofs.close();  LOG(INFO, "保存到⽂件完毕\n");  }  if (_next) _next->Execute(file);  else LOG(DEBUG, "到达责任链结尾,本次任务处理完毕\n");  }  
};  
文件分片处理节点
const int default_maxline = 5; // 可配置的最大行数  // 检测文件大小并分片  
class HandleBackUp : public Handler {  
private:  std::string _filepath;  std::string _filename;  int _maxline;  // 生成带时间戳的备份后缀  virtual std::string GetCurrTime() override {  time_t now_time = time(nullptr);  struct tm *curr_time = localtime(&now_time);  char buf[128];  snprintf(buf, sizeof(buf), ".%d_%02d_%02d_%02d_%02d_%02d_%d",  curr_time->tm_year + 1900, curr_time->tm_mon + 1,  curr_time->tm_mday, curr_time->tm_hour,  curr_time->tm_min, curr_time->tm_sec, getpid());  return buf;  }  // 检查文件是否超过分片阈值  bool IsOutRange(const std::string &file) {  std::ifstream ifs(file);  if (!ifs.is_open()) return false;  int lines = 0;  std::string line;  while (std::getline(ifs, line)) ++lines;  ifs.close();  return lines > _maxline;  }  // 执行分片备份(子进程处理)  void BackUp(const std::string &file) {  std::string suffix = GetCurrTime();  std::string backfilename = file + suffix;  std::string tgzfilesrc = _filename + suffix;  std::string tgzfiledst = tgzfilesrc + ".tgz";  pid_t pid = fork();  if (pid == 0) {  std::filesystem::rename(file, backfilename);  std::filesystem::current_path(_filepath);  execlp("tar", "tar", "-czf", tgzfiledst.c_str(),  tgzfilesrc.c_str(), nullptr);  exit(1);  }  }  public:  HandleBackUp(const std::string &filepath = default_filepath,  const std::string &filename = default_filename,  int maxline = default_maxline)  : _filepath(filepath), _filename(filename), _maxline(maxline) {}  void Execute(const std::string &text) override {  if (_isEnable) {  std::string file = _filepath + _filename;  if (IsOutRange(file)) BackUp(file);  LOG(INFO, "分⽚检测处理完毕\n");  }  if (_next) _next->Execute(text);  else LOG(DEBUG, "到达责任链结尾,本次任务处理完毕\n");  }  
};  
责任链入口
// 责任链入口类  
class HandlerEntry {  
private:  std::shared_ptr<HandlerFormatText> _format;  std::shared_ptr<HandleSaveFile> _save;  std::shared_ptr<HandleBackUp> _backup;  public:  HandlerEntry() {  // 初始化节点  _format = std::make_shared<HandlerFormatText>();  _save = std::make_shared<HandleSaveFile>();  _backup = std::make_shared<HandleBackUp>();  // 连接责任链  _format->SetNext(_save);  _save->SetNext(_backup);  // 处理子进程僵尸状态  signal(SIGCHLD, [](int signum) {  int status = 0;  pid_t id = 0;  while ((id = waitpid(-1, &status, WNOHANG)) > 0) {  if (WIFEXITED(status)) {  LOG(DEBUG, "删除临时备份文件: %s\n", delfile.c_str());  std::filesystem::remove(delfile);  }  }  });  }  // 执行责任链处理  void Run(std::string &text) {  _format->Execute(text);  }  
};  

4. 模式特点

  • 解耦性:发送者与接收者解耦,请求处理逻辑可动态组合。
  • 扩展性:新增处理节点无需修改原有代码,符合开闭原则。
  • 灵活性:可通过启用/禁用节点动态调整处理流程(如Enable/Disable方法)。

通过结合SystemV消息队列与责任链模式,可实现高效的进程间通信及灵活的消息处理流水线,满足消息格式化、持久化及分片等复杂业务需求。

相关文章:

SystemV-消息队列与责任链模式

一、SystemV 消息队列 1. 消息队列API Ftok 函数定义&#xff1a; key_t ftok(const char *pathname, int proj_id);函数作用&#xff1a; 获取唯一的key值标识符&#xff0c;用于标识系统V消息队列。参数解释&#xff1a; pathname&#xff1a;有效的文件路径&#xff08;需…...

Ubuntu与Linux的关系

Linux 是一个 操作系统内核。它是一个类 Unix 系统&#xff0c;免费、开源&#xff0c;许多不同的操作系统&#xff08;叫“发行版”&#xff09;都是基于 Linux 内核构建的。 Ubuntu 是一个 基于 Linux 内核的操作系统发行版。它是目前最流行、最易用的 Linux 发行版之一&…...

同时支持windows和Linux的NFC读写器web插件

一个网站集成了NFC读写器的功能&#xff0c;如何才能跨系统运行呢&#xff0c;既要在windows系统下正常运行&#xff0c;也需要在银河麒麟&#xff0c;统信UOS等信创系统下运行。 友我科技NFC读写器web插件很好的解决了这个问题&#xff0c;在客户端不仅支持windows系统&#x…...

突破AI检测边界:对抗技术与学术伦理的终极博弈

随着GPT-4、Claude等大模型的文本生成能力突破人类写作水平&#xff0c;AI检测工具与对抗技术的博弈已进入白热化阶段。本文深入解析基于对抗训练的文本风格混淆网络如何突破GPTZero最新防御体系&#xff0c;探讨OpenAI多模态内容溯源系统引发的技术升级&#xff0c;并针对学术…...

pg数据库删除自建表空间

1. tbs_sjzx已经创建&#xff08;略&#xff09; pg数据库删除自己创建表空间;--查看表空间相关表 SELECT * FROM pg_tablespace; SELECT relname FROM pg_class WHERE reltablespace (SELECT oid FROM pg_tablespace WHERE spcname tbs_sjzx); SELECT * FROM pg_tables WHE…...

C++ 学习指南

new 关键字 #include <iostream> using namespace std;int* func() {// 在堆区创建int* p new int(10); return p; }void test01(void) {int *p func();cout << *p << endl;cout << *p << endl;cout << *p << endl;delete p;// 这…...

Scribe: 一个非常方便的操作文档编写工具

在日常生活中&#xff0c;当我们需要指导别人使用一个软件/web应用时&#xff0c;我们常常需要按流程对工具进行操作&#xff0c;走一遍主要功能&#xff0c;然后针对每一步进行截图&#xff0c;并附上操作说明。往往这样一套流程走下来&#xff0c;就会花费很长的时间。那么有…...

数据结构与算法-顺序表应用

一.通讯录的创建 首先我们要理解的是通讯录本身就是以顺序表为底层的 只不过顺序表中的数组&#xff0c;这里我们是用结构体来替代&#xff0c;用来存储用户的信息 由于是通讯录的本质就是顺序表&#xff0c;所以顺序表的任何方法它都能套用 Contact.h: #pragma once #def…...

DeepSeek系列(5):助力数据分析

数据解读与可视化建议 在数据驱动的商业环境中,有效解读数据并将其转化为直观可视化结果至关重要。DeepSeek作为强大的AI助手,可以帮助您从海量数据中提取洞见并提供专业的可视化建议。 DeepSeek在数据解读中的优势 DeepSeek可以通过以下方式帮助您更高效地解读数据: 上下…...

虚幻基础:动画k帧

文章目录 动画k帧&#xff1a;调整骨骼的变换达到自己想要的效果步骤打开动画原始文件选中骨骼调整到目标变换添加关键帧时间&#xff1a;自动添加到停留的那一帧数值&#xff1a;自动填写为调整后的数值 注释数值与骨骼细节面板上的数值并不对应&#xff0c;但是同样的效果为什…...

使用 LlamaIndex Workflows 与 Elasticsearch

作者&#xff1a;来自 Elastic Jeffrey Rengifo 在本文中&#xff0c;你将学习如何利用 LlamaIndex Workflows 与 Elasticsearch 快速构建一个使用 LLM 的自过滤搜索应用程序。 LlamaIndex Workflows 提出了一种不同的方式来处理将任务拆分给不同 agent 的问题&#xff0c;它引…...

相对论大师-记录型正负性质BFS/图论-链表/数据结构

看到这一题我的第一个思路就是双向bfs 起点是a&#xff0c;终点还是a&#xff0c;但是flag是相反的&#xff08;“越”的方向&#xff09; tip1.可以用字典vis来存储flag 刚开始初始化时vissta,visend一个对应0、1 要求两个队列相…...

代理设计模式:从底层原理到源代码的详细解释

代理设计模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它通过创建一个代理对象来控制对目标对象的访问。代理对象充当客户端和目标对象之间的中介&#xff0c;允许在不修改目标对象的情况下添加额外的功能&#xff08;如权限控制、日志记录、延迟…...

EasyRTC音视频实时通话:打造高清低延迟的远程会议新生态

一、项目背景​ 随着数字化办公的普及&#xff0c;远程会议成为企业、教育机构、政府部门等组织跨地域协作沟通的重要方式。传统远程会议系统在音视频质量、低延迟传输、多平台兼容性等方面存在不足&#xff0c;难以满足用户对高清、流畅、稳定会议体验的需求。EasyRTC作为一款…...

零基础上手Python数据分析 (21):图表选择困难症?常用可视化类型详解与应用场景指南

写在前面 —— 告别盲目绘图,理解图表语言,为你的数据找到最佳“代言人” 在前面几篇博客中,我们已经学习了使用 Matplotlib 和 Seaborn 这两大 Python 可视化利器来绘制各种图表。我们掌握了创建折线图、柱状图、散点图、箱线图等常用图表的技术。然而,仅仅知道 如何 绘…...

HarmonyOS Next 编译之如何使用多目标产物不同包名应用

引言 在日常的开发中涉及到多签名和多产物构建输出时手动切换签名文件和包名在开发中是容易出错且费时的一个操作&#xff0c;鸿蒙提供了自定义hvigor插件和多目标产物构建&#xff0c;那我们可以通过hvigor插件来动态修改不同项目配置所需要的代码&#xff0c;保证一套代码在…...

Oracle Database Resident Connection Pooling (DRCP) 白皮书阅读笔记

本文为“Extreme Oracle Database Connection Scalability with Database Resident Connection Pooling (DRCP)”的中文翻译加阅读笔记。觉得是重点的就用粗体表示了。 白皮书版本为March 2025, Version 3.3&#xff0c;副标题为&#xff1a;Optimizing Oracle Database resou…...

Sharding-JDBC 系列专题 - 第七篇:Spring Boot 集成与 Sharding-Proxy 简介

Sharding-JDBC 系列专题 - 第七篇:Spring Boot 集成与 Sharding-Proxy 简介 本系列专题旨在帮助开发者全面掌握 Sharding-JDBC,一个轻量级的分布式数据库中间件。本篇作为系列的第七篇文章,将重点探讨 Sharding-JDBC 与 Spring Boot 的集成,以及 Sharding-Proxy 的基本概念…...

day30 学习笔记

文章目录 前言一、凸包特征检测1.穷举法2.QuickHull法 二、图像轮廓特征查找1.外接矩形2.最小外接矩形3.最小外接圆 前言 通过今天的学习&#xff0c;我掌握了OpenCV中有关凸包特征检测&#xff0c;图像轮廓特征查找的相关原理和操作 一、凸包特征检测 通俗的讲&#xff0c;凸…...

变更管理 Change Management

以下是关于项目管理中 变更管理 的深度解析,结合高项(如软考高级信息系统项目管理师)教材内容,系统阐述变更管理的理论框架、流程方法及实战应用: 一、变更管理的基本概念 1. 定义 变更管理是对项目范围、进度、成本、质量等基准的修改进行系统性控制的过程,旨在确保变…...

PaddlePaddle线性回归详解:从模型定义到加载,掌握深度学习基础

目录 前言一、paddlepaddle框架的线性回归1.1 paddlepaddle模型的定义方式1.1.1 使用序列的方式 nn.Sequential 组网1.1.2 使用类的方式 class nn.Layer组网1.2 数据加载 1.3 paddlepaddle模型的保存1.3.1 基础API保存1.3.2 高级API模型的保存1.3.2.1 训练fit进行保存1.3.2.2 …...

几种Word转换PDF的常用方法

使用 Word 内置功能 步骤&#xff1a;打开需要转换的 Word 文档&#xff0c;点击左上角的 “文件” 菜单&#xff0c;选择 “另存为”&#xff0c;选择保存位置&#xff0c;在 “保存类型” 下拉菜单中选择 “PDF”&#xff0c;点击 “保存” 按钮即可。适用场景&#xff1a;适…...

【美化vim】

美化vim 涉及文件一个例子 涉及文件 ~/.vimrc修改这个文件即可 一个例子 let mapleader ,set number " 显示行号"set relativenumber " 显示相对行号set incsearch " 实时开启搜索高亮set hlsearch " 搜索结果高亮set autoinden…...

【git】subtree拆分大的git库到多个独立git库

【git】subtree拆分大的git库到多个独立git库 一、拆分一个子目录为独立仓库 # 这就是那个大仓库 big-project git clone gitgithub.com:tom/big-project.git cd big-project# 把所有 eiyo 目录下的相关提交整理为一个新的分支 eiyo_code git subtree split -P eiyo -b eiyo_…...

Elasticsearch 使用reindex进行数据同步或索引重构

1、批量复制优化 POST _reindex {"source": {"index": "source","size": 5000},"dest": {"index": "dest"} }2、提高scroll的并行度优化 POST _reindex?slices5&refresh {"source": {…...

JDBC对数据的增删改查操作:从Statement到PrepareStatement

目录 一 . Statement简介 二. 通过Statement添加数据 1. 创建表 2. 通过Statement添加数据 a. 获取连接 b. 获取Statement对象 c. 定义SQL语句 d. 执行SQL语句 e. 关闭资源 3. 通过Statement修改数据 4. 通过Statement删除数据 三. PreparedStatement的使用(重点) …...

智体OS上线智体管家:对话式智体应用商店访问

DTNS.OS 更新公告 - 智体管家功能发布 &#x1f31f; 2024年4月22日重要更新&#xff1a;智体管家正式上线 智体管家是智体OS推出的全新功能&#xff0c;旨在让用户通过自然对话轻松发现和使用智体节点上的所有智体应用&#xff0c;相当于为智体网络打造了一个智能化的应用商…...

vscode flutter 插件, vscode运行安卓项目,.gradle 路径配置

Flutter Flutter Widget Snippets Awesome Flutter Snippets i dart-import Dart Data Class Generator Json to Dart Model Dart Getters And Setter GetX Snippets GetX Generator GetX Generator for Flutter flutter-img-syncvscode运行安卓项目&#xff0c;.gradle 路径配…...

dolphinscheduler实现(oracle-hdfs-doris)数据ETL

dolphinscheduler执行 完整脚本(自行替换相关变量)配置文件conf配置文件解析脚本转base64脚本 完整脚本(自行替换相关变量) user_olsh conf/getInfo.sh Oracle user conf/databases.conf password_olsh conf/getInfo.sh Oracle password conf/databases.conf dblink_olsh conf…...

ViewBS 的工作流程

ViewBS ViewBS 的工作流程 ViewBS 提供多个顶级命令,用于确定所需和最优参数。这些命令可分为两部分:甲基化报告和功能区域的数据可视化。 在甲基化报告部分中,提供多个顶级命令,可以生成关于读取覆盖度、甲基化水平分布、全局甲基化水平等报告。 在功能区域可视化部分…...

qt调用deepseek的API开发(附带源码)

今天讲的是使用qt做一个界面&#xff08;负责接受deepseek返回的数据和客户发送数据的端口&#xff09;会用流的方式接受数据提高用户体验 测试效果源码流程配置deepseek调用思路deepseek与qt联合开发界面思路 上一篇文章用的不是流开发&#xff0c;会让客户等待很久&#xff0…...

java中值传递的含义

Java 中的值传递&#xff08;Pass by Value&#xff09;详解 在 Java 中&#xff0c;所有参数的传递都是值传递&#xff08;Pass by Value&#xff09;&#xff0c;但根据传递的数据类型不同&#xff08;基本类型 vs 引用类型&#xff09;&#xff0c;表现行为会有所不同。 1.…...

【自然语言处理与大模型】如何知道自己部署的模型的最大并行访问数呢?

当你自己在服务器上部署好一个模型后&#xff0c;使用场景会有两种。第一种就是你自己去玩&#xff0c;结合自有的数据做RAG等等&#xff0c;这种情况下一般是不会考虑并发的问题。第二种是将部署好的服务给到别人来使用&#xff0c;这时候就必须知道我的服务到底支持多大的访问…...

基于PHP+MySQL实现(Web)单词助手网站

WordHelper 这是一个学习 PHP 的时候依照课程设计的要求&#xff0c;做的一个简单的单词助手。 系统通过 CDN 引入 Vue.js 和 ElementUI&#xff0c;并用 PHP 搭建了一个十分十分简易的后台。 一、设计要求 1、词汇录入与编辑。提供接口让用户录入英文单词、词义、发音、词…...

Java面试实战:谢飞机的求职记 - Spring Boot、Redis与微服务技术问答解析

场景描述 谢飞机&#xff0c;一位自称为“Java全栈大师”的程序员&#xff0c;参加了某互联网大厂的Java开发岗位面试。面试官严肃而专业&#xff0c;针对Spring Boot、Redis缓存以及微服务架构等核心技术展开提问。以下是谢飞机在面试中的表现。 第一轮提问&#xff08;基础篇…...

【数字图像处理】立体视觉信息提取

双目立体视觉原理 设一个为参考平面&#xff0c;一个为目标平面。增加了一个摄像头后&#xff0c;P与Q在目标面T上有分别的成像点 双目立体视觉&#xff1a;从两个不同的位置观察同一物体&#xff0c;用三角测量原理计算摄像机到该物体的距离的 方法 原理&#xff1a;三角测量…...

解析芯片低功耗设计的底层逻辑与实现方法

芯片低功耗设计的必要性可以从实际需求和技术优化两方面来探讨&#xff1a; 从需求角度看&#xff0c;工艺进步和应用场景共同驱动低功耗设计。 随着CMOS制程持续微缩&#xff0c;晶体管密度和时钟频率提升导致静态功耗显著增加&#xff0c;漏电流问题在先进工艺中尤为明显。…...

uniapp开发2--uniapp中的条件编译总结

以下是对 uni-app 中条件编译的总结&#xff1a; 概念&#xff1a; 条件编译是一种技术&#xff0c;允许你根据不同的平台或环境&#xff0c;编译不同的代码。 在 uni-app 中&#xff0c;这意味着你可以编写一套代码&#xff0c;然后根据要编译到的平台&#xff08;例如微信小…...

Netty 异步机制深度解析:Future 与 Promise 的前世今生

引言&#xff1a;异步编程的「糖」与「痛」 在高性能网络编程中&#xff0c;「异步」几乎是必备的设计模式&#xff0c;异步的好处就是可以提升系统吞吐量&#xff0c;提升效率。但很多开发者初入 Netty 时&#xff0c;对它的异步机制总有点模糊&#xff1a; 为什么 ChannelF…...

如何查看MySql主从同步的偏移量

1.Mysql的主从同步方案 mysql为了在实现读写分离&#xff0c;主库写&#xff0c;从库读 mysql的同步方案主要是通过从库读取主库的binlog日志的方式。 binlog就是一个记录mysql的操作的日志记录&#xff0c;从库通过拿到主库的binlog知道主库进行了哪些操作&#xff0c;然后在从…...

短信验证码安全实战:三网API+多语言适配开发指南

在短信服务中&#xff0c;创建自定义签名是发送通知、验证信息和其他类型消息的重要步骤。万维易源提供的“三网短信验证码”API为开发者和企业提供了高效、便捷的自定义签名创建服务&#xff0c;可以通过简单的接口调用提交签名给运营商审核。本文将详细介绍如何使用该API&…...

护眼-科学使用显示器

一 显示色温对眼睛的影响 显示器的色温设置对护眼效果至关重要&#xff0c;合适的色温可减少蓝光伤害并缓解视疲劳。最护眼的色温并非固定值&#xff0c;需根据环境光、使用时间和场景动态调整。白天推荐6500K左右&#xff0c;夜晚降至3000K-4000K&#xff0c;并借助自动调节工…...

HarmonyOS:1.7

判断题 1.订阅网络状态变化事件时&#xff0c;通过NetConnection类型的对象调用on方法&#xff0c;传入具体事件类型即可&#xff1a; 错误(False) 2.若使用HTTP发起一个GET请求&#xff0c;直接调用get方法&#xff0c;传入请求资源的URL&#xff0c;即可发起请求&#xff…...

物联网赋能玻璃制造业:实现设备智能管理与生产协同

在当今数字化时代&#xff0c;物联网技术正深刻改变着传统制造业的发展模式&#xff0c;玻璃制造业也不例外。物联网的赋能&#xff0c;为玻璃制造业带来了设备智能管理与生产协同的新机遇&#xff0c;推动其向智能化、高效化迈进。 在设备智能管理方面&#xff0c;物联网通过…...

【我的创作纪念日】 --- 与CSDN走过的第365天

个人主页&#xff1a;夜晚中的人海 不积跬步&#xff0c;无以至千里&#xff1b;不积小流&#xff0c;无以成江海。-《荀子》 文章目录 &#x1f389;一、机缘&#x1f680;二、收获&#x1f3a1;三、 日常⭐四、成就&#x1f3e0;五、憧憬 &#x1f389;一、机缘 光阴似箭&am…...

路由器转发规则设置方法步骤,内网服务器端口怎么让异地连接访问的实现

在路由器上设置端口转发&#xff08;Port Forwarding&#xff09;可以将外部网络流量引导到特定的局域网设备&#xff0c;这对于需要远程访问服务器、摄像头、游戏主机等设备非常有用。 登录路由器管理界面&#xff0c;添加端口转发规则让外网访问内网的实现教程分享。以下是设…...

Kotlin 的 suspend 关键字

更多相关知识 Kotlin 的 suspend 关键字是 Kotlin 协程的核心组成部分&#xff0c;它用于标记一个函数可以被挂起&#xff08;暂停执行&#xff09;并在稍后恢复执行&#xff0c;而不会阻塞线程。 理解 suspend 的作用需要从以下几个方面入手&#xff1a; 1. 允许非阻塞的异步…...

Java面试实战:从Spring Boot到微服务的深入探讨

Java面试实战&#xff1a;从Spring Boot到微服务的深入探讨 场景&#xff1a;电商场景的面试之旅 在某互联网大厂的面试间&#xff0c;面试官李老师正襟危坐&#xff0c;而对面坐着的是传说中的“水货程序员”赵大宝。 第一轮&#xff1a;核心Java与构建工具 面试官&#x…...

文件操作和IO(上)

绝对路径和相对路径 文件按照层级结构进行组织&#xff08;类似于数据结构中的树型结构&#xff09;&#xff0c;将专门用来存放管理信息的特殊文件称为文件夹或目录。对于文件系统中文件的定位有两种方式&#xff0c;一种是绝对路径&#xff0c;另一种是相对路径。 绝对路径…...

【Dify(v1.2) 核心源码深入解析】Apps 模块

重磅推荐专栏&#xff1a; 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域&#xff0c;包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用&#xff0c;以及与之相关的人工智能生成内容&#xff…...