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

QT_dbus(ipc进程间通讯)

QT_dbus(ipc进程间通讯)

前言:
参考链接:
https://www.cnblogs.com/brt3/p/9614899.html
https://blog.csdn.net/weixin_43246170/article/details/120994311
https://blog.csdn.net/kchmmd/article/details/118605315
一个大型项目可能需要多个子程序同时运行,但是子程序之间的通讯就需要进程间通讯,DBUS是QT自带的组件,尝试使用一下。

1、创建包含多个子程序的工程
在这里插入图片描述
在这里插入图片描述

TEMPLATE = subdirs

在这里插入图片描述

2、第一个dbus试验:先建立session bus的连接,然后使用QT自带工具qdbusviewer演示使用
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

#include "mainwidget.h"
#include "qdebug.h"
#include "dbus/RPCClient.h"
#include "dbus/DBUSServer.h"
#include "dbus/MessageTip.h"
#include <QProcess>#include <QtDBus/QtDBus>
#include <QDBusError>MainWidget::MainWidget()
{QQmlApplicationEngine *m_pEngine = new QQmlApplicationEngine;QQmlComponent component(m_pEngine, QUrl(QStringLiteral("qrc:/main.qml")));QObject *mainObject = component.create();if (mainObject == nullptr) {qDebug() << "mainObject fail";return;}// 用于建立到session bus的连接QDBusConnection bus = QDBusConnection::sessionBus();// 在session bus上注册名为"com.test.hotel"的serviceif (!bus.registerService("com.test.hotel")) {qDebug() << bus.lastError().message();exit(1);}//一定要用实例化这种形式,使用定义的方式不行DBUSServer *dbusserver = new DBUSServer();// 注册名为"/dbusserver"的object。// "QDBusConnection::ExportAllSlots"表示把类DBUSServer的所有Slot都导出为这个Object的methodbus.registerObject("/dbusserver", dbusserver, QDBusConnection::ExportAllSlots);//bus.registerObject("/dbusserver", dbusserver, QDBusConnection::ExportAllSignal);
}

DBUSServer.cpp

#include "DBUSServer.h"
#include "qdebug.h"DBUSServer::DBUSServer()
{connect(this, SIGNAL(opendoor()), this, SLOT(onopenlight()));
}void DBUSServer::oncheckIn()
{qDebug() << "checkIn";emit opendoor();
}
void DBUSServer::oncheckOut()
{qDebug() << "oncheckOut";
}
void DBUSServer::onopenlight()
{qDebug() << "onopenlight";
}
int DBUSServer::onquery()
{return 50;
}

DBUSServer.h

#ifndef DBUSSERVER_H
#define DBUSSERVER_H
#include <QObject>
#include <QBrush>
class DBUSServer : public QObject
{Q_OBJECT
public:DBUSServer();public slots:void oncheckIn();void oncheckOut();int onquery();void onopenlight();signals:// Check in,参数为房间数,返回成功拿到的房间数void opendoor();private:int m_rooms;//QReadWriteLock m_lock;};
#endif // RPCSERVER_H

3、综合试验,经过几天的研究,决定以后采用下面的方法来进行进程间通讯
方法一:
说明:类似信号和槽(我个人认为是类似于MQTT协议的订阅和发布机制),

//函数说明:在不同进程之间建立信号和槽的关系,"on_hello"是自定义的信号的名(也可认为是发布的主题)
//参数1:服务器地址,参数2:路径(不填),参数3:Interface名称(不填),参数4:自定义信号(可认为是订阅信号),参数5:槽函数所在的对象,参数6:槽函数
QDBusConnection::sessionBus().connect("com.test.hotel", "", "", "on_hello", this, SLOT(onApplyvalueChanged(int)));//函数说明:真正发布消息的地方,只要是和"on_hello"建立连接的槽函数都会得到相应
QDBusMessage msg = QDBusMessage::createSignal("/dbusserver", "com.test.hotel", "on_hello");
msg << 456;  //如果带参数就这样加上要传的参数
QDBusConnection::sessionBus().send(msg);

方法二:
说明:这种方法虽然思路清晰,但是调用一次函数代码量比较多,不是太推荐

//参数1:服务器地址,参数2:路径,参数3:Interface名称,参数4:调用槽函数的名字
QDBusMessage message = QDBusMessage::createMethodCall("com.test.hotel","/dbusserver","com.test.hotel.show","oncheckIn");
//槽函数有几种情况:①有参数传入无参数返回,②有参数传入有参数返回,③无参数传入有参数返回
/*****************有参数传入有参数返回*****************/
message << 123;//给int oncheckIn(int value);这个槽函数传入的参数(如果没有参数需要传,此步骤不用写)
//发送消息并获取返回值
QDBusMessage response = QDBusConnection::sessionBus().call(message);
//判断method是否被正确返回
if (response.type() == QDBusMessage::ReplyMessage) 
{//从返回参数获取返回值int value = response.arguments().takeFirst().toInt();qDebug() << QString("value =  %1").arg(value);
} 
else 
{qDebug() << "value method called failed!";
}/*****************有参数传入无参数返回*****************/
message << 123;//给int oncheckIn(int value);这个槽函数传入的参数(如果没有参数需要传,此步骤不用写)
//发送消息
QDBusMessage response = QDBusConnection::sessionBus().call(message);
//判断method是否被正确返回
if (response.type() == QDBusMessage::ReplyMessage) 
{qDebug() << "value method called successfull";
} 
else 
{qDebug() << "value method called failed!";
}/*****************无参数传入无参数返回*****************/
//发送消息
QDBusMessage response = QDBusConnection::sessionBus().call(message);
//判断method是否被正确返回
if (response.type() == QDBusMessage::ReplyMessage) 
{qDebug() << "value method called successfull";
} 
else 
{qDebug() << "value method called failed!";
}

方法三:
说明:这种方法虽然思路清晰,比方法二更简介一些,推荐使用

//参数1:服务器地址,参数2:路径,参数3:Interface名称
QDBusInterface interface("com.test.hotel", "/dbusserver", "com.test.hotel.show", QDBusConnection::sessionBus());
if (!interface.isValid()) {qDebug() << "dbus interface fail";return;
}
QDBusMessage response;
//调用槽函数分为三种:①有参数传入无参数返回,②有参数传入有参数返回,③无参数传入有参数返回
//response = interface.call("onquery", 158);//有参数传入有参数返回
response = interface.call("onquery");//无参数传入有参数返回/有参数传入无参数返回
//判断method是否被正确返回
if (response.type() == QDBusMessage::ReplyMessage) {//从返回参数获取返回值(没有返回值的返回0,有返回值的正常返回)int value = response.arguments().takeFirst().toInt();qDebug() << QString("value =  %1").arg(value);
} 
else 
{qDebug() << "value method called failed!";
}

工程源码展示:
在这里插入图片描述

test_rpc.pro

TEMPLATE = subdirsSUBDIRS += \apply \layer

apply/apply.pro

QT += quick \widgets \dbusCONFIG += c++11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Refer to the documentation for the
# deprecated API to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \Dbusclass.cpp \main.cpp \mainwidget.cppRESOURCES += qml.qrc# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetHEADERS += \Dbusclass.h \mainwidget.h

apply/Headers/Dbusclass.h

#ifndef DBUSCLASS_H
#define DBUSCLASS_H
#include <QObject>
#include <QBrush>
class Dbusclass : public QObject
{Q_OBJECT//定义Interface名称为:"com.test.hotel.show"Q_CLASSINFO("D-Bus Interface", "com.test.apply.show")
public:Dbusclass();public slots:int oncheckIn(int value);//有参数传入有参数返回void oncheckOut(int value);//有参数传入无参数返回int onquery();//无参数传入有参数返回void onopenlight();//无参数传入无参数返回signals:void opendoor();private:int m_rooms;
};
#endif // RPCSERVER_H

apply/Headers/mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H#include <QObject>
#include <QWidget>
#include <QQmlComponent>
#include <QQmlApplicationEngine>
#include <QQuickItem>
#include "Dbusclass.h"class MainWidget : public QObject
{Q_OBJECTpublic:MainWidget();protected slots:void onClickPageNo(bool enable);void onApplyvalueChanged(int value);void onApplystringChanged(QString value);void oncreateSignal();void onqDBusMessage();void onqDBusInterface();private:QQuickItem *m_applyItem = nullptr;QObject *m_applyObject = nullptr;
};#endif // MAINWIDGET_H

apply/Sources/Dbusclass.cpp

#include "Dbusclass.h"
#include "qdebug.h"
#include <QDebug>Dbusclass::Dbusclass()
{connect(this, SIGNAL(opendoor()), this, SLOT(onopenlight()));
}int Dbusclass::oncheckIn(int value)
{qDebug() << "checkIn:" << value;emit opendoor();return value;
}
void Dbusclass::oncheckOut(int value)
{qDebug() << "oncheckOut:" << value;
}
void Dbusclass::onopenlight()
{qDebug() << "onopenlight";
}
int Dbusclass::onquery()
{return 50;
}

apply/Sources/mainwidget.cpp

#include "mainwidget.h"
#include "qdebug.h"
#include "Dbusclass.h"
#include <QProcess>#include <QtDBus/QtDBus>
#include <QDBusError>
#include <QDBusMessage>MainWidget::MainWidget()
{QQmlApplicationEngine *m_pEngine = new QQmlApplicationEngine;QQmlComponent component(m_pEngine, QUrl(QStringLiteral("qrc:/main.qml")));QObject *mainObject = component.create();if (mainObject == nullptr) {qDebug() << "mainObject fail";return;}QList<QObject *> objectList = mainObject->findChildren<QObject *>("mybutton");if (objectList.isEmpty()) {qDebug() << "mybutton failed\n";return;}m_applyObject = objectList.last();connect(m_applyObject, SIGNAL(applyvalueChanged(int)), this, SLOT(onApplyvalueChanged(int)));connect(m_applyObject, SIGNAL(applystringChanged(QString)), this, SLOT(onApplystringChanged(QString)));connect(mainObject, SIGNAL(window_interface(bool)), this, SLOT(onClickPageNo(bool)));connect(mainObject, SIGNAL(createSignal()), this, SLOT(oncreateSignal()));connect(mainObject, SIGNAL(qDBusMessage()), this, SLOT(onqDBusMessage()));connect(mainObject, SIGNAL(qDBusInterface()), this, SLOT(onqDBusInterface()));// 用于建立到session bus的连接QDBusConnection bus = QDBusConnection::sessionBus();// 在session bus上注册名为"com.test.hotel"的serviceif (!bus.registerService("com.test.apply")) {qDebug() << bus.lastError().message();exit(1);}//一定要用实例化这种形式,使用定义的方式不行Dbusclass *dbusapply = new Dbusclass();// 注册名为"/dbusserver"的object。// "QDBusConnection::ExportAllSlots"表示把类DBUSServer的所有Slot都导出为这个Object的methodbus.registerObject("/dbusapply", dbusapply, QDBusConnection::ExportAllSlots);//bus.registerObject("/dbusapply", dbusapply, QDBusConnection::ExportAllSignal);//参数1:服务器地址,参数2:路径,参数3:Interface名称(不填),参数4:自定义信号(可认为是订阅信号),参数5:槽函数所在的对象,参数6:槽函数QDBusConnection::sessionBus().connect("com.test.layer", "", "", "on_layer", this, SLOT(onApplyvalueChanged(int)));
}void MainWidget::onClickPageNo(bool enable)
{//打开子程序QProcess *process = new QProcess();process->start("/home/zhou/work/test/build-test_rpc-Desktop_Qt_5_14_2_GCC_64bit-Debug/layer/layer");
}void MainWidget::onApplyvalueChanged(int value)
{qDebug() << "onApplyvalueChanged" << value;
}void MainWidget::onApplystringChanged(QString value)
{qDebug() << "onApplystringChanged" << value;
}void MainWidget::oncreateSignal()
{qDebug() << "oncreateSignal" ;QDBusMessage msg = QDBusMessage::createSignal("/dbuslayer", "com.test.layer.show", "on_apply");msg << 456;QDBusConnection::sessionBus().send(msg);
}void MainWidget::onqDBusMessage()
{qDebug() << "onqDBusMessage" ;QDBusMessage message = QDBusMessage::createMethodCall("com.test.layer","/dbuslayer","com.test.layer.show","oncheckIn");message << 234;//发送消息QDBusMessage response = QDBusConnection::sessionBus().call(message);//判断method是否被正确返回if (response.type() == QDBusMessage::ReplyMessage) {//从返回参数获取返回值int value = response.arguments().takeFirst().toInt();qDebug() << QString("value =  %1").arg(value);} else {qDebug() << "value method called failed!";}
}void MainWidget::onqDBusInterface()
{qDebug() << "onqDBusInterface" ;QDBusInterface interface("com.test.layer", "/dbuslayer", "com.test.layer.show", QDBusConnection::sessionBus());if (!interface.isValid()) {qDebug() << "dbus interface fail";return;}QDBusMessage response;response = interface.call("oncheckIn", 158);    // 有参数//判断method是否被正确返回if (response.type() == QDBusMessage::ReplyMessage) {//从返回参数获取返回值int value = response.arguments().takeFirst().toInt();qDebug() << QString("value =  %1").arg(value);} else {qDebug() << "value method called failed!";}
}

apply/Sources/main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "mainwidget.h"
#include "qdebug.h"
#include "qthread.h"int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);//    QQmlApplicationEngine engine;
//    const QUrl url(QStringLiteral("qrc:/main.qml"));
//    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
//    &app, [url](QObject * obj, const QUrl & objUrl) {
//        if (!obj && url == objUrl) {
//            QCoreApplication::exit(-1);
//        }
//    }, Qt::QueuedConnection);
//    engine.load(url);MainWidget mainwidget;return app.exec();
}

apply/main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12Window {visible: truewidth: 640height: 480objectName: "apply_window"title: qsTr("Hello apply")signal window_interface(bool enable)signal createSignal()signal qDBusMessage()signal qDBusInterface()Column{anchors.fill: parentspacing: 20Button{width: 140height: 50text: "开启界面2"onClicked: {window_interface(true)}}Button{width: 140height: 50text: "createSignal_发布消息"onClicked: {createSignal()}}Button{width: 140height: 50text: "QDBusMessage"onClicked: {qDBusMessage()}}Button{width: 140height: 50text: "QDBusInterface"onClicked: {qDBusInterface()}}Mybutton{width: 140height: 300}}
}

apply/Mybutton.qml

import QtQuick 2.0
import QtQuick.Controls 2.12Item {objectName: "mybutton"signal applyvalueChanged(int value)signal applystringChanged(string value)Column{spacing: 10Button{objectName: "button"width: 140height: 50text: "send1"onClicked: {applyvalueChanged(1)}}Button{width: 140height: 50text: "send2"onClicked: {applyvalueChanged(2)}}Button{width: 140height: 50text: "验证string"onClicked: {applystringChanged("{\"name\":\"lili\",\"age\":24,\"class\":6}")}}}
}

layer.pro

QT += quick
QT += widgets
QT += dbusCONFIG += c++11# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Refer to the documentation for the
# deprecated API to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \dbusclass.cpp \main.cpp \mainwidget.cppRESOURCES += qml.qrc# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetHEADERS += \dbusclass.h \mainwidget.h

layer/Herders/dbusclass.h

#ifndef DBUSCLASS_H
#define DBUSCLASS_H#include <QObject>class Dbusclass : public QObject
{Q_OBJECT//定义Interface名称为:"com.test.layer.show"Q_CLASSINFO("D-Bus Interface", "com.test.layer.show")
public:Dbusclass();public slots:int oncheckIn(int value);//有参数传入有参数返回
};#endif // DBUSCLASS_H

layer/Herders/mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H#include <QObject>
#include <QQmlComponent>
#include <QQmlApplicationEngine>
#include <QQuickItem>class mainwidget : public QObject
{Q_OBJECT
public:mainwidget();public slots:void oncreateSignal();void onqDBusMessage();void onqDBusInterface();void onMessage_recv(int num);private:
};#endif // MAINWIDGET_H

layer/Sources/dbusclass.cpp

#include "dbusclass.h"
#include <QDebug>Dbusclass::Dbusclass()
{}int Dbusclass::oncheckIn(int value)
{qDebug() << "checkIn:" << value;return value;
}

layer/Sources/mainwidget.cpp

#include "mainwidget.h"
#include "dbusclass.h"
#include <QDBusMessage>
#include <QDBusConnection>
#include <QDBusInterface>
#include <QtDBus/QtDBus>mainwidget::mainwidget()
{QQmlApplicationEngine *m_pEngine = new QQmlApplicationEngine;QQmlComponent component(m_pEngine, QUrl(QStringLiteral("qrc:/main.qml")));QObject *mainObject = component.create();if (mainObject == nullptr) {qDebug() << "mainObject fail";return;}// 用于建立到session bus的连接QDBusConnection bus = QDBusConnection::sessionBus();// 在session bus上注册名为"com.test.hotel"的serviceif (!bus.registerService("com.test.layer")) {qDebug() << bus.lastError().message();exit(1);}//一定要用实例化这种形式,使用定义的方式不行Dbusclass *dbusclass = new Dbusclass();// 注册名为"/dbuslayer"的object。// "QDBusConnection::ExportAllSlots"表示把类DBUSServer的所有Slot都导出为这个Object的methodbus.registerObject("/dbuslayer", dbusclass, QDBusConnection::ExportAllSlots);connect(mainObject, SIGNAL(createSignal()), this, SLOT(oncreateSignal()));connect(mainObject, SIGNAL(qDBusMessage()), this, SLOT(onqDBusMessage()));connect(mainObject, SIGNAL(qDBusInterface()), this, SLOT(onqDBusInterface()));QDBusConnection::sessionBus().connect("com.test.apply", "", "", "on_apply", this, SLOT(onMessage_recv(int)));
}void mainwidget::oncreateSignal()
{qDebug() << "oncreateSignal";QDBusMessage msg = QDBusMessage::createSignal("/dbusapply", "com.test.apply.show", "on_layer");msg << 123;QDBusConnection::sessionBus().send(msg);
}void mainwidget::onqDBusMessage()
{qDebug() << "onLayer_reduce";QDBusMessage message = QDBusMessage::createMethodCall("com.test.apply","/dbusapply","com.test.apply.show","oncheckIn");message << 234;//发送消息QDBusMessage response = QDBusConnection::sessionBus().call(message);//判断method是否被正确返回if (response.type() == QDBusMessage::ReplyMessage) {//从返回参数获取返回值int value = response.arguments().takeFirst().toInt();qDebug() << QString("value =  %1").arg(value);} else {qDebug() << "value method called failed!";}
}void mainwidget::onqDBusInterface()
{qDebug() << "onLayer_reduce";QDBusInterface interface("com.test.apply", "/dbusapply", "com.test.apply.show", QDBusConnection::sessionBus());if (!interface.isValid()) {qDebug() << "dbus interface fail";return;}QDBusMessage response;response = interface.call("oncheckIn", 158);    // 有参数
//    response = interface.call("oncheckOut");    // 无参数
//    response = interface.call("onopenlight");//判断method是否被正确返回if (response.type() == QDBusMessage::ReplyMessage) {//从返回参数获取返回值int value = response.arguments().takeFirst().toInt();qDebug() << QString("value =  %1").arg(value);} else {qDebug() << "value method called failed!";}
}void mainwidget::onMessage_recv(int num)
{qDebug() << "onMessage_recv:" << num;
}

layer/Sources/main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "qdebug.h"
#include "mainwidget.h"int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);//    QQmlApplicationEngine engine;
//    const QUrl url(QStringLiteral("qrc:/main.qml"));
//    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
//    &app, [url](QObject * obj, const QUrl & objUrl) {
//        if (!obj && url == objUrl) {
//            QCoreApplication::exit(-1);
//        }
//    }, Qt::QueuedConnection);
//    engine.load(url);mainwidget mainwidget;return app.exec();
}

layer/main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12Window {visible: truewidth: 640height: 480title: qsTr("Hello layer")signal createSignal()signal qDBusMessage()signal qDBusInterface()Column{anchors.fill: parentspacing: 20Button{width: 140height: 50text: "createSignal_发布消息"onClicked: {createSignal()}}Button{width: 140height: 50text: "QDBusMessage"onClicked: {qDBusMessage()}}Button{width: 140height: 50text: "QDBusInterface"onClicked: {qDBusInterface()}}}
}

相关文章:

QT_dbus(ipc进程间通讯)

QT_dbus(ipc进程间通讯) 前言&#xff1a; 参考链接&#xff1a; https://www.cnblogs.com/brt3/p/9614899.html https://blog.csdn.net/weixin_43246170/article/details/120994311 https://blog.csdn.net/kchmmd/article/details/118605315 一个大型项目可能需要多个子程序同…...

华为OD机试 - 数组排序(C++) | 附带编码思路 【2023】

刷算法题之前必看 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12199283.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 华为OD机试题…...

字符串转换为二进制-课后程序(JAVA基础案例教程-黑马程序员编著-第五章-课后作业)

【案例5-4】 字符串转换为二进制 【案例介绍】 1.任务描述 本例要求编写一个程序&#xff0c;从键盘录入一个字符串&#xff0c;将字符串转换为二进制数。在转换时&#xff0c;将字符串中的每个字符单独转换为一个二进制数&#xff0c;将所有二进制数连接起来进行输出。 案…...

SpringIOC

一、为什么要使用Spring&#xff1f; Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用&#xff0c;但是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应用开发&#xff0c;并通过POJO为基础的编程模型促进良好的编程习惯。 为…...

Debezium系列之:基于数据库信号表和Kafka信号Topic两种技术方案实现增量快照incremental技术的详细步骤

Debezium系列之:基于数据库信号表和Kafka信号Topic两种技术方案实现增量快照incremental技术的详细步骤 一、需求背景二、增量快照技术实现的两种方案三、基于数据库信号表实现增量快照技术的原理1.基于水印的快照2.信令表3.增量快照4.连接起重启四、基于数据库信号表实现增量…...

华为OD机试 - 第 K 个最小码值的字母(Python) | 机试题+算法思路+考点+代码解析 【2023】

第 K 个最小码值的字母 题目 输入一个由n个大小写字母组成的字符串 按照 ASCII 码值从小到大进行排序 查找字符串中第k个最小 ASCII 码值的字母(k>=1) 输出该字母所在字符串中的位置索引(字符串的第一个位置索引为 0) k如果大于字符串长度则输出最大 ASCII 码值的字母所在…...

PointNet++训练自己的数据集(附源码)

本文针对PointNet强大的三维点云分类功能&#xff0c;详细讲解怎么训练自己的数据集&#xff0c;在此之前&#xff0c;需要确保已经能够跑通源码的训练和测试&#xff0c;如果没有&#xff0c;请参考PointNet的源码运行。数据放置1.1. 在mytensor_shape_names.txt中配置自己的分…...

ROS2可视化利器---Foxglove Studio

0. 简介 之前作者已经讲了《ROS1可视化利器—Webviz》&#xff0c;然后就有读者问&#xff0c;ROS2有没有可以使用的可视化工具呢&#xff0c;答案是肯定的&#xff0c;除了plotjuggler这种ROS1和ROS2通用的可视化利器&#xff0c;还有一种全平台通用的软件FoxgloveStudio&…...

python实战应用讲解-【语法基础篇】流程控制-控制流的元素及语句(附示例代码)

目录 控制流的元素 条件 代码块 程序执行 代码块嵌套 控制流语句 if 语句...

[蓝桥杯 2019 省 A] 外卖店优先级

蓝桥杯 2019 年省赛 A 组 G 题题目描述“饱了么”外卖系统中维护着 N家外卖店&#xff0c;编号 1 ∼ N。每家外卖店都有一个优先级&#xff0c;初始时 (0 时刻&#xff09;优先级都为0。每经过 1 个时间单位&#xff0c;如果外卖店没有订单&#xff0c;则优先级会减少 1&#x…...

Jetson Xavier nx(ubuntu18.04)安装rtl8152网卡驱动和8192网卡驱动

含义 Bus 002 : 指明设备连接到哪条总线。 Device 003 : 表明这是连接到总线上的第二台设备。 ID : 设备的ID&#xff0c;包括厂商的ID和产品的ID&#xff0c;格式 厂商ID&#xff1a;产品ID。 Realtek Semiconductor Corp. RTL8153 Gigabit Ethernet Adapter:生产商名字和设备…...

Rocky 9.1操作系统实现zabbix6.0的安装部署实战

文章目录前言一. 实验环境二. 安装zabbix过程2.1. 安装zabbix源2.2 安装zabbix相关的软件2.3 安装数据库并启动2.4 开始初始化数据库&#xff1a;2.5 创建数据库实例及对应的用户2.6 导入官网提供的数据2.7 配置zabbix 服务的配置文件2.8. 启动服务2.9 从网页进行安装2.10 登陆…...

AQS-ReentrantLock

一、AQS 在 Lock 中&#xff0c;用到了一个同步队列 AQS&#xff0c;全称 AbstractQueuedSynchronizer&#xff0c;它是一个同步工具&#xff0c;也是 Lock 用来实现线程同步的核心组件。 1.AQS 的两种功能 独占和共享。 独占锁&#xff1a;每次只能有一个线程持有锁&#x…...

SpringCloud+Dubbo3 = 王炸 !

前言 全链路异步化的大趋势来了 随着业务的发展&#xff0c;微服务应用的流量越来越大&#xff0c;使用到的资源也越来越多。 在微服务架构下&#xff0c;大量的应用都是 SpringCloud 分布式架构&#xff0c;这种架构总体上是全链路同步模式。 全链路同步模式不仅造成了资源…...

机器学习主要内容的思维导图

机器学习 机器学习&#xff1a; 定义&#xff1a;能够从经验中学习从而能够 把事情不断做好的计算机程序 人工智能的一个分支和 实现方式 理论基础&#xff1a;概率论 数理统计 线性代数 数学分析 数值逼近 最优化理论 计算复杂理论 核心要素&#xff1a;数据 算法 模型 机器…...

嵌套走马灯Carousel

Carousel 的应用很广泛&#xff0c;基础用法这里不多做阐述&#xff0c;感兴趣的可以去element-gui了解Carousel 组件。 今天主要是梳理嵌套走马灯的逻辑&#xff0c;背景如下&#xff1a; 需要对项目做一个展示&#xff0c;项目可能有一个或多个&#xff0c;同时一个项目可能…...

实战——缓存的使用

文章目录前言概述实践一、缓存数据一致1.更新缓存类2.删除缓存类二、项目实践&#xff08;商城项目&#xff09;缓存预热双缓存机制前言 对于我们日常开发的应用系统。由于MySQL等关系型数据库读写的并发量是有一定的上线的&#xff0c;当请求量过大时候那数据库的压力一定会上…...

2023年中职网络安全竞赛跨站脚本渗透解析-2(超详细)

跨站脚本渗透 任务环境说明:需求环境可私信博主! 服务器场景:Server2126(关闭链接)服务器场景操作系统:未知访问服务器网站目录1,根据页面信息完成条件,将获取到弹框信息作为flag提交;访问服务器网站目录2,根据页面信息完成条件,将获取到弹框信息作为flag提交;访问…...

Scala的简单使用

文章目录Scala的简单使用&#xff08;一&#xff09;交互模式1、命令行方式2、文件方式&#xff08;二&#xff09;编译模式1、创建源程序2、编译成字节码3、解释执行对象Scala的简单使用 Scala可以在交互模式和编译模式两种方式下运行 &#xff08;一&#xff09;交互模式 在…...

Java之前缀和算法

目录 一.前缀和 1.前缀和介绍 2.编程中的前缀和 二.一维数组的动态和 1.题目描述 2.问题分析 3.代码实现 三.除自身以外数组的乘积 1.题目描述 2.问题分析 3.代码实现 四.和为 K 的子数组 1.题目描述 2.问题分析 3.代码实现 五.形成两个异或相等数组的三元组数目…...

基于GIS计算降雨侵蚀力R因子

一、数据来源介绍 &#xff08;一&#xff09;行政边界数据 本文所用到的河北唐山行政边界数据来源于中国科学院资源环境科学与数据中心&#xff08;https://www.resdc.cn/Default.aspx&#xff09;。 &#xff08;二&#xff09;降水量数据 本文所用到的降水量数据来源于国家…...

大数据时代下的企业网络安全

在大数据技术迅猛发展的今天&#xff0c;网络安全问题已经发展成一个广受关注的热门研究方向。有人说&#xff0c;“大数据下&#xff0c;人人裸奔”&#xff0c;隐私保护、数据防护日益成为广大学者、企业研究的焦点。 面对这种安全威胁&#xff0c;企业必须实施一些有效的信…...

【跟我一起读《视觉惯性SLAM理论与源码解析》】第三章第四章 SLAM中常用的数学基础知识相机成像模型

齐次坐标能大大简化在三维空间中点、线、面表达方式和旋转、平移等操作在齐次坐标下&#xff0c;两个点的叉积结果可以表示一条直线l;也可以用两条直线的叉积结果表示它们的齐次坐标交点&#xff0c;关于叉积其实十四讲解释的还是比较清楚的&#xff0c;和李代数李群的关系可以…...

LeetCode 242. 有效的字母异位词

242. 有效的字母异位词 难度&#xff1a;easy\color{Green}{easy}easy 题目描述 给定两个字符串 sss 和 ttt &#xff0c;编写一个函数来判断 ttt 是否是 sss 的字母异位词。 注意&#xff1a; 若 sss 和 ttt 中每个字符出现的次数都相同&#xff0c;则称 sss 和 ttt 互为字…...

力扣mysql刷题记录

mysql刷题记录 刷题链接https://leetcode.cn/study-plan/sql/?progressjkih0qc mysql冲&#xff01;mysql刷题记录1699. 两人之间的通话次数1251. 平均售价1571. 仓库经理1445. 苹果和桔子1193. 每月交易 I1633. 各赛事的用户注册率1173. 即时食物配送 I1211. 查询结果的质量…...

Linux基础命令-lsof查看进程打开的文件

Linux基础命令-uptime查看系统负载 Linux基础命令-top实时显示系统状态 Linux基础命令-ps查看进程状态 文件目录 前言 一 命令的介绍 二 语法及参数 2.1 使用help查看命令的语法信息 2.2 常用参数 2.2.lsof命令-i参数的条件 三 命令显示内容的含义 3.1 FD 文件描述符的…...

常用电平标准

现在常用的电平标准有TTL CMOS LVTTL LVCMOS LVDS PCI等&#xff0c;下面简单介绍一下各自的供电电源、电平标准及注意事项数字电路中&#xff0c;由TTL电子元件组成电路使用的电平。电平是个电压范围。标准输出高电平(VOH): 2.4V标准输出低电平(VOL)&#xff1a;0.4V通常输出高…...

小程序开发注意点

1.组件样式隔离注意点 2.methods方法 3.自定义组件的properties参数 4.自定义组件的事件监听 5.纯数据字段 6.插槽 单个插槽 启用多插槽 使用多个插槽 7.属性绑定实现父传子功能 例如在这里有一个组件为<one></one>&#xff0c;那么可以在组件当中传入参数 &l…...

自行车出口欧盟CE认证,新版自行车标准ISO 4210:2023与ISO 8098:2023发布

2023年1月&#xff0c;国际标准化组织ISO发布了新版“自行车以及儿童自行车的测试标准”&#xff0c;即ISO 4210&#xff1a;2023以及ISO 8098:2023&#xff0c;用于取代了SO 4210&#xff1a;2015以及ISO 8098:2015。新版标准一经发布&#xff0c;立即生效。欧盟标准化委员会C…...

2020蓝桥杯真题回文日期 C语言/C++

题目描述 2020 年春节期间&#xff0c;有一个特殊的日期引起了大家的注意&#xff1a;2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202&#xff0c;恰好是一个回文数。我们称这样的日期是回文日期。 有人表示 20200202 是 “千年一遇…...