seo建站要求/免费广告发布平台

seo建站要求,免费广告发布平台,做网站需要apache,东莞网站建设管理Qt互斥锁【QMutex】的使用、QMutexLocker的使用 基于读写锁(QReadWriteLock)的线程同步Chapter1 Qt互斥锁(QMutex)的使用、QMutexLocker的使用一、QMutexLocker和QMutex实现示例图二、QMutex和QMutexLocker的关系(个人理解)三、QMutex使用和QMutexLocker…

Qt互斥锁【QMutex】的使用、QMutexLocker的使用

  • 基于读写锁(QReadWriteLock)的线程同步
  • Chapter1 Qt互斥锁(QMutex)的使用、QMutexLocker的使用
    • 一、QMutexLocker和QMutex实现示例图
    • 二、QMutex和QMutexLocker的关系(个人理解)
    • 三、QMutex使用和QMutexLocker使用
      • 1.QMutex的使用
      • 2.QMutexLocker的使用
    • 四、检验QMutexLocker是否将传入的互斥锁锁定
      • 1.操作解释
      • 2.CMoveFuncClass(使用moveToThread实现,使用QMutexLocker)
      • 3.CThread类(继承QThread实现,单纯使用QMutex)
      • 4.CMainWindow调用类
    • 总结
    • 相关文章
  • Chapter2 QReadWriteLock读写锁
    • 1、读写锁的特性:读共享,写独占。
    • 2、读写优先级
    • 3、常用函数包含:
    • 4、常关联的类包含:
  • Chapter3 QT多线程(二):基于互斥锁与读写锁的线程同步
    • 1. 线程同步概念
    • 2. 基于互斥量的线程同步
      • 2.1 QMutex类
      • 2.2 QMutexLocker 类
    • 3. 基于读写锁的线程同步


基于读写锁(QReadWriteLock)的线程同步

使用互斥量时存在一个问题,即每次只能有一个线程获得互斥量的使用权限。如果在一个程序中有多个线程读取某个变量,使用互斥量时必须排队。而实际上若只是读取一个变量,可以让多个线程同时访问,这种情况下使用互斥量就会降低程序的性能。

因此提出了读写锁概念,Qt 提供了读写锁类 QReadWriteLock,它是基于读或写的方式进行代码片段锁定的,在多个线程读写一个共享数据时,使用它可以解决使用互斥量存在的上面所提到的问题。

QReadWriteLock 以 读或写锁定的同步方法允许以读或写的方式保护一段代码,它可以允许多个线程以只读方式同步访问资源,但是只要有一个线程在以写入方式访问资源,其他线程就必须等待,直到写操作结束。

简单总结就是:同一时间,多个线程可以同时读,只有一个线程可以写,读写不能同时进行。

Chapter1 Qt互斥锁(QMutex)的使用、QMutexLocker的使用

原文链接:https://blog.csdn.net/wj584652425/article/details/123585126

一、QMutexLocker和QMutex实现示例图

下图为检测QMutexLocker是否上锁成功的示例图(两个线程使用同一个QMutex),源码在文章第四节(源码含详细注释)。

下图为不同QMutex运行时的效果(该图表明两个线程无关,并非sleep影响了另一个线程的运行)

二、QMutex和QMutexLocker的关系(个人理解)

互斥锁(QMutex)在使用时需要在进入和结束的时候使用对应的函数锁定和解锁。在简单的程序中还好,但是在结构复杂的程序中因为需要手动锁定和解锁,很容易忽略细节而出现问题,于是为了应对这种情况QMutexLocker便诞生了(为了简化简化互斥锁的锁定和解锁)。
QMutexLocker通常创建为局部变量,QMutexLocker在创建时传入一个并未锁定(若是锁定可用relock重新锁定或unlock解锁)的QMutex指针变量,并且会将QMutex变量锁定,在释放时会将QMutex变量解锁。(QMutexLocker创建时将传入的QMutex锁定,释放时将传入的QMutex解锁)

三、QMutex使用和QMutexLocker使用

1.QMutex的使用

void CThread::run()
{//互斥锁锁定m_mutex->lock();//输出当前线程的线程IDqDebug() << QThread::currentThreadId();//互斥锁解锁m_mutex->unlock();
}

2.QMutexLocker的使用

void CThread::run()
{//创建QMutexLocker的局部变量,并将类中互斥锁指针传入(此处互斥锁被locker锁定)QMutexLocker locker(m_mutex);qDebug() << QThread::currentThreadId();//当locker作用域结束locker将互斥锁解锁
}

通过1、2的代码比较,我们会发现QMutexLocker的代码中没有手动调用锁定和解锁,由此可看出MutexLocker简化了互斥锁的锁定和解锁。

四、检验QMutexLocker是否将传入的互斥锁锁定

1.操作解释

使用两种实现方法完全不同线程测试
两个线程使用同一个互斥锁
一个线程使用QMutexLocker一个线程单纯使用QMutex

2.CMoveFuncClass(使用moveToThread实现,使用QMutexLocker)

CMoveFuncClass.h

#ifndef CMOVEFUNCCLASS_H
#define CMOVEFUNCCLASS_H#include <QObject>
#include <QMutex>class CMoveFuncClass : public QObject
{Q_OBJECT
public:explicit CMoveFuncClass(QObject *parent = nullptr);~CMoveFuncClass();void setMutex(QMutex *mutex);public slots:void doSomething();private:QMutex * m_mutex;   //定义一个互斥锁变量
};#endif // CMOVEFUNCCLASS_H

CMoveFuncClass.cpp

#include "CMoveFuncClass.h"#include <QDebug>
#include <QThread>CMoveFuncClass::CMoveFuncClass(QObject *parent): QObject(parent)
{
}CMoveFuncClass::~CMoveFuncClass()
{
}void CMoveFuncClass::doSomething()
{//创建QMutexLocker的局部变量,并将类中互斥锁指针传入(此处互斥锁被locker锁定)QMutexLocker locker(m_mutex);qDebug() << "我的实现方法为moveToThread" <<"开始3秒睡眠" << "使用QMutexLocker";qDebug() << "线程ID:" << QThread::currentThreadId();QThread::sleep(3);  //设置线程睡眠3秒(单位为秒)qDebug() << "我的实现方法为moveToThread" <<"线程运行完成,结束睡眠\n\n";//当locker作用域结束locker将互斥锁解锁
}void CMoveFuncClass::setMutex(QMutex *mutex)
{m_mutex = mutex;
}

3.CThread类(继承QThread实现,单纯使用QMutex)

CThread.h

#ifndef CTHREAD_H
#define CTHREAD_H#include <QObject>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>class CThread : public QThread
{Q_OBJECT
public:explicit CThread(QObject *parent = nullptr);~CThread();void run();void setMutex(QMutex *mutex);private:QMutex *            m_mutex;            //定义一个线程锁变量};#endif // CTHREAD_H

CThread.cpp

#include "CThread.h"
#include <QDebug>CThread::CThread(QObject *parent): QThread(parent)
{
}CThread::~CThread()
{
}void CThread::run()
{//互斥锁上锁m_mutex->lock();qDebug() << "我的实现方法为继承QThread" << "开始3秒睡眠" << "单纯使用QMutex";qDebug() << "线程ID:" << QThread::currentThreadId();QThread::sleep(3);  //设置线程睡眠3秒(单位为秒)qDebug() << "我的实现方法为继承QThread" <<"线程运行完成,结束睡眠";//互斥锁解锁m_mutex->unlock();
}void CThread::setMutex(QMutex *mutex)
{m_mutex = mutex;
}

4.CMainWindow调用类

CMainWindow.h

#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H#include <QMainWindow>
#include "CThread.h"
#include "CMoveFuncClass.h"namespace Ui {
class CMainWindow;
}class CMainWindow : public QMainWindow
{Q_OBJECTpublic:explicit CMainWindow(QWidget *parent = 0);~CMainWindow();signals:void startMoveThread();private slots:void on_startBtn_clicked();		//触发方法二函数的信号private:Ui::CMainWindow *ui;CThread         *m_cThread;		//方法一指针CMoveFuncClass  *m_moveFunc;	//方法二指针QThread         *m_thread;		//方法二所移至的线程指针QMutex          *m_mutex;       //两个线程使用的线程锁
};#endif // CMAINWINDOW_H

CMainWindow.cpp

#include "CMainWindow.h"
#include "ui_CMainWindow.h"#include <QDebug>CMainWindow::CMainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::CMainWindow)
{ui->setupUi(this);/方法一/////new出CThread对象m_cThread = new CThread;/方法二/////new一个moveToThread的接收线程并启动m_thread = new QThread;//new出CMoveFuncClass对象m_thread->start();  //一定记得启动,否则运行不了m_moveFunc = new CMoveFuncClass;//连接相应信号槽connect(this, &CMainWindow::startMoveThread, m_moveFunc, &CMoveFuncClass::doSomething);connect(m_thread, &QThread::finished, m_moveFunc, &QObject::deleteLater);//将对象移至线程m_moveFunc->moveToThread(m_thread);//创建线程共用的互斥锁m_mutex = new QMutex;//下方为m_mutex的地方更改为new QMutex,则能实现第一节,第二张图的效果m_cThread->setMutex(m_mutex);m_moveFunc->setMutex(m_mutex);
}CMainWindow::~CMainWindow()
{delete m_mutex;delete m_moveFunc;m_thread->exit();m_thread->wait(1);delete m_thread;m_cThread->exit();m_cThread->wait(1);delete m_cThread;delete ui;
}void CMainWindow::on_startBtn_clicked()
{//通过start启动方法一线程m_cThread->start();//发送信号启动方法二线程emit startMoveThread();
}

运行上方的代码(第一节,第一张效果图)可看出,使用QMutexLocker的线程首先运行,且代码中无锁定和解锁的操作,但另外一个线程依然等该线程运行完成后运行,由此可看出,使用QMutexLocker是实现了互斥锁的锁定和解锁的。

总结

QMutexLocker提供的简化互斥锁锁定和解锁的机制在很多时候时蛮方便的,在使用互斥锁的地方使用QMutexLocker会减去许多安全隐患;不过在多线程循环输出ABC的时候好像就不适合该方法。所以使用类似的类还得按情况而定

相关文章

启动QThread线程的两种方法(含源码+注释)
Qt互斥锁(QMutex)、条件变量(QWaitCondition)讲解+QMutex实现多线程循环输出ABC(含源码+注释)
QSemaphore的使用+QSemaphore实现循环输出ABC(含源码+注释)
QRunnable线程、QThreadPool(线程池)的使用(含源码+注释)
Qt读写锁(QReadWriteLock)的使用、读写锁的验证(含源码+注释)
Qt读写锁(QWriteLocker、QReadLocker)的理解和使用(含部分源码)
Qt之线程运行指定函数(含源码+注释,优化速率)

友情提示——哪里看不懂可私哦,让我们一起互相进步吧
(创作不易,请留下一个免费的赞叭 谢谢 o/)

注:文章为作者编程过程中所遇到的问题和总结,内容仅供参考,若有错误欢迎指出。
注:如有侵权,请联系作者删除

Chapter2 QReadWriteLock读写锁

原文链接:https://blog.csdn.net/weixin_43246170/article/details/121015495

QT中线程间的同步分别有QMutex互斥锁、QSemephone信号量、QWaitCondition条件变量和QReadWriteLock读写锁四种方式。

这边来介绍的是读写锁,一般应用与具有大量读操作的场景。

1、读写锁的特性:读共享,写独占。

读共享 :
当其他线程占用读锁的时候,如果其他线程请求读锁,会立即获得。
当其他线程占用读锁的时候,如果其他线程请求写锁,会阻塞等待读锁的释放。
写独占 :
当其他线程占用写锁的时候,如果其他线程请求读锁,会阻塞等待写锁的释放。
当其他线程占用写锁的时候,如果其他线程请求写锁,会阻塞等待写锁的释放。

2、读写优先级

默认优先级是写优先,即写锁的优先级>读锁,哪怕是读先排队的也没用。

3、常用函数包含:

lockForRead() ; 请求读锁
lockForWrite() ; 请求写锁
tryLockForRead() ; 尝试请求读锁,非阻塞函数,可以设置超时时间。
tryLockForWrite() ; 尝试请求写锁,非阻塞函数,可以设置超时时间。
unlock() ; 解锁(解读锁和解写锁,均使用该函数)

4、常关联的类包含:

QReadLocker;
QWriteLocker;

Chapter3 QT多线程(二):基于互斥锁与读写锁的线程同步

原文链接:https://blog.csdn.net/qq_46144191/article/details/144494017

此处需要说明的是,这里的线程同步概念与操作系统中的线程同步并无区别,都是避免多个线程同时访问临界区数据可能产生的读写错误问题。在 Qt 中,有多个类可以实现线程同步的功能,这些类包括 QMutex、QMutexLocker、 QReadWriteLock、QReadLocker、QWriteLocker、QWaitCondition、QSemaphore 等。

1. 线程同步概念

在多线程程序中,由于存在多个线程,线程之间可能需要访问同一个变量,或一个线程需要等待另一个线程完成某个操作后才产生相应的动作。例如在上一节中提到的例程,工作线程生成随机的骰子点数,主线程读取骰子点数并显示,主线程需要等待工作线程生成一新的骰子点数后再读取数据。但上一节中并没有使用线程同步机制,而是使用了信号与槽的机制,在生成新的点数之后通过

信号通知主线程读取新的数据。这个过程类似于操作系统的线程信号机制,都是为信号设定一个处理函数,本章中不使用信号与槽函数来讲解其他方式的线程同步方法。

2. 基于互斥量的线程同步

QMutex 和 QMutexLocker 是基于互斥量(mutex)的线程同步类。

2.1 QMutex类

该类提供的API函数如下:

void QMutex::lock() //锁定互斥量,一直等待
void QMutex::unlock() //解锁互斥量
bool QMutex::tryLock() //尝试锁定互斥量,不等待
bool QMutex::tryLock(int timeout) //尝试锁定互斥量,最多等待 timeout 毫秒

函数 lock()锁定互斥量,如果另一个线 程锁定了这个互斥量,它将被阻塞运行直到 其他线程解锁这个互斥量。函数 unlock()解锁互斥量,需要与 lock()配对使用。

函数 tryLock()尝试锁定一个互斥量,如果成功锁定就返回 true,如果其他线程已经锁定了这个互斥量就返回 false。函数 tryLock(int timeout)尝试锁定一个互斥量,如果这个互斥量被其他线程锁定,最多等待 timeout 毫秒。

互斥量相当于一把钥匙,如果两个线程要访问同一个共享资源,就需要通过 lock()或 tryLock()拿到这把钥匙,然后才可以访问该共享资源,访问完之后还要通过unlock()还回钥匙,这样别的线程才有机会拿到钥匙。

在这里插入图片描述

在上一节的例程中,在TDiceThread类中添加一个QMutex变量,并删除自定义信号newValue(),增加一个readValue()函数用于提供给主窗口访问类变量。

QMutex  mutex;  //互斥量bool TDiceThread::readValue(int *seq, int *diceValue)
{if (mutex.tryLock(100))  //尝试锁定互斥量,等待100ms{*seq=m_seq;*diceValue=m_diceValue;mutex.unlock();     //解锁互斥量return true;}elsereturn false;
}

主函数(主线程)在访问m_seq和m_diceValue变量时,会尝试获取“钥匙”,最多等待100ms,得到权限后会通过指针类变量返回值。事后解锁以便于工作线程对这两个变量进行修改。

另一处需修改的是工作线程中的访问,代码如下:

void TDiceThread::run()
{//线程的事件循环m_stop=false;       //启动线程时令m_stop=falsem_paused=true;      //启动运行后暂时不掷骰子m_seq=0;            //掷骰子次数while(!m_stop)      //循环主体{if (!m_paused){mutex.lock();       //锁定互斥量m_diceValue=0;for(int i=0; i<5; i++)m_diceValue += QRandomGenerator::global()->bounded(1,7);  //产生随机数[1,6]m_diceValue =m_diceValue/5;m_seq++;mutex.unlock();     //解锁互斥量}msleep(500);    //线程休眠500ms}quit();     //在  m_stop==true时结束线程任务
}

在函数 run()中,我们对重新计算变量 m_diceValue 和 m_seq 值的代码片段用互斥量 mutex 进行了保护。工作线程运行后,其内部的函数 run()一直在运行。主线程里调用工作线程的 readValue()函数,其实际是在主线程里运行的。

通过上述方式,主线程和工作线程都对临界区的变量进行了互斥访问,这样就可确保数据的完整性。

2.2 QMutexLocker 类

QMutexLocker 是另一个简化了互斥量处理的类。QMutexLocker 的构造函数接受互斥量作为参数并将其锁定,QMutexLocker 的析构函数则将此互斥量解锁,所以在 QMutexLocker 实例变量的生存期内的代码片段会得到保护,自动进行互斥量的锁定和解锁。

void TDiceThread::run()
{//线程的事件循环m_stop=false;       //启动线程时令m_stop=falsem_paused=true;      //启动运行后暂时不掷骰子m_seq=0;            //掷骰子次数while(!m_stop)      //循环主体{if (!m_paused){QMutexLocker locker(&mutex);m_diceValue=0;for(int i=0; i<5; i++)m_diceValue += QRandomGenerator::global()->bounded(1,7);  //产生随机数[1,6]m_diceValue =m_diceValue/5;m_seq++;}msleep(500);    //线程休眠500ms}quit();     //在  m_stop==true时结束线程任务
}

这两种实现互斥访问的功能一样,使用是分别注意其形式即可。

在主窗口类的构造函数中,设置了一个定时器,每隔一段时间读取一次临界区变量,如果成功获取到锁并且数据也是最新的,则据此更新主界面。

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);threadA= new TDiceThread(this);connect(threadA,&TDiceThread::started, this, &MainWindow::do_threadA_started);connect(threadA,&TDiceThread::finished,this, &MainWindow::do_threadA_finished);timer= new QTimer(this);     //创建定时器timer->setInterval(200);timer->stop();connect(timer,&QTimer::timeout, this, &MainWindow::do_timeOut);
}void MainWindow::do_timeOut()
{int tmpSeq=0,tmpValue=0;bool  valid=threadA->readValue(&tmpSeq,&tmpValue); //读取数值if (valid && (tmpSeq != m_seq)) //有效,并且是新数据{m_seq=tmpSeq;m_diceValue=tmpValue;QString  str=QString::asprintf("第 %d 次掷骰子,点数为:%d",m_seq,m_diceValue);ui->plainTextEdit->appendPlainText(str);QString filename=QString::asprintf(":/dice/images/d%d.jpg",m_diceValue);QPixmap pic(filename);ui->labPic->setPixmap(pic);}}

在开始和结束按钮槽函数中,需要设置定时器的启动和停止。代码如下:

void MainWindow::on_actDice_Run_triggered()
{//"开始"按钮,开始掷骰子threadA->diceBegin();timer->start();     //重启定时器ui->actDice_Run->setEnabled(false);ui->actDice_Pause->setEnabled(true);
}void MainWindow::on_actDice_Pause_triggered()
{//"暂停"按钮,暂停掷骰子threadA->dicePause();timer->stop();      //停止定时器ui->actDice_Run->setEnabled(true);ui->actDice_Pause->setEnabled(false);
}

3. 基于读写锁的线程同步

使用互斥量时存在一个问题,即每次只能有一个线程获得互斥量的使用权限。如果在一个程序中有多个线程读取某个变量,使用互斥量时必须排队。而实际上若只是读取一个变量,可以让多个线程同时访问,这种情况下使用互斥量就会降低程序的性能。

因此提出了读写锁概念,Qt 提供了读写锁类 QReadWriteLock,它是基于读或写的方式进行代码片段锁定的,在多个线程读写一个共享数据时,使用它可以解决使用互斥量存在的上面所提到的问题。

QReadWriteLock 以 读或写锁定的同步方法允许以读或写的方式保护一段代码,它可以允许多个线程以只读方式同步访问资源,但是只要有一个线程在以写入方式访问资源,其他线程就必须等待,直到写操作结束。

简单总结就是:同一时间,多个线程可以同时读,只有一个线程可以写,读写不能同时进行。

QReadWriteLock类 提供以下几个主要的函数:

void lockForRead() //以只读方式锁定资源,如果有其他线程以写入方式锁定资源,这个函数会被阻塞
void lockForWrite() //以写入方式锁定资源,如果其他线程以读或写方式锁定资源,这个函数会被阻塞
void unlock() //解锁
bool tryLockForRead() //尝试以只读方式锁定资源,不等待
bool tryLockForRead(int timeout) //尝试以只读方式锁定资源,最多等待 timeout 毫秒
bool tryLockForWrite() //尝试以写入方式锁定资源,不等待
bool tryLockForWrite(int timeout) //尝试以写入方式锁定资源,最多等待 timeout 毫秒

例如下列案例:

int buffer[100]; 
QReadWriteLock Lock; //定义读写锁变量
void ThreadDAQ::run() //负责采集数据的线程
{ ... Lock.lockForWrite(); //以写入方式锁定get_data_and_write_in_buffer(); //数据写入 buffer Lock.unlock();... 
} 
void ThreadShow::run() //负责显示数据的线程
{ ... Lock.lockForRead(); //以读取方式锁定show_buffer(); //读取 buffer 里的数据并显示Lock.unlock(); ... 
} 
void ThreadSaveFile::run() //负责保存数据的线程
{ ... Lock.lockForRead(); //以读取方式锁定save_buffer_toFile(); //读取 buffer 里的数据并保存到文件Lock.unlock(); ... 
}

另外,QReadLocker 和 QWriteLocker 是 QReadWriteLock 的简便形式,如同 QMutexLocker 是 QMutex 的简便形式一样,无须与 unlock()配对使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/71184.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot ——简单开发流程实战

本文使用SpringBoot进行电商系统商品数据增删改查的简单开发流程。 本文目录 一、创建Spring Boot项目二、配置数据库连接三、创建实体类四、创建Repository接口五、创建Service层六、创建Controller层七、测试 一、创建Spring Boot项目 可以通过https://start.spring.io/或者…

fastadmin 后台商品sku(vue)

先上个效果图 首先先引入vue define([backend], function (Backend) {require.config({paths: {vue: /assets/jeekshopskugoods/libs/vue.min,skuimg: /assets/jeekshopskugoods/js/skuimg,skugoods: /assets/jeekshopskugoods/js/skugoods,layui: /assets/LayuiSpzj/layui/la…

C++蓝桥杯基础篇(六)

片头 嗨~小伙伴们&#xff0c;大家好&#xff01;今天我们来一起学习蓝桥杯基础篇&#xff08;六&#xff09;&#xff0c;练习相关的数组习题&#xff0c;准备好了吗&#xff1f;咱们开始咯&#xff01; 第1题 数组的左方区域 这道题&#xff0c;实质上是找规律&#xff0c;…

git -学习笔记

目录 基本操作语法 设置用户和邮箱 版本回退 工作区和暂存区 撤销修改 删除与恢复 一工作区删除了&#xff0c;但是暂存区没删除 二工作区误删了&#xff0c;暂存区还有 github-Git 连接 报错解决-push远程仓库被拒绝 远程库 分支 分支冲突 储藏分支 回到当前分…

Windows本地Docker+Open-WebUI部署DeepSeek

最近想在自己的电脑本地部署一下DeepSeek试试&#xff0c;由于不希望污染电脑的Windows环境&#xff0c;所以在wsl中安装了ollama&#xff0c;使用ollama拉取DeepSeek模型。然后在Windows中安装了Docker Desktop&#xff0c;在Docker中部署了Open-WebUI&#xff0c;最后再在Ope…

力扣785. 判断二分图

力扣785. 判断二分图 题目 题目解析及思路 题目要求将所有节点分成两部分&#xff0c;每条边的两个端点都必须在不同集合中 二分图&#xff1a;BFS/DFS/并查集 因为图不一定联通&#xff0c;所以枚举所有点都做bfs(如果没联通的话) 代码 class Solution { public:bool is…

springboot之集成Elasticsearch

目录 二、Elasticsearch 是什么&#xff1f;三、Elasticsearch 安装四、Springboot 集成 Elasticsearch 的方式五、创建项目集成 Elasticsearch 2.创建 Spring Initializr 项目 es &#xff08;3&#xff09;.新建实体类 User&#xff08;4&#xff09;.新建 dao 接口类 UserR…

[Lc滑动窗口_1] 长度最小的数组 | 无重复字符的最长子串 | 最大连续1的个数 III | 将 x 减到 0 的最小操作数

目录 1. 长度最小的字数组 题解 代码 ⭕2.无重复字符的最长子串 题解 代码 3.最大连续1的个数 III 题解 代码 4.将 x 减到 0 的最小操作数 题解 代码 1. 长度最小的字数组 题目链接&#xff1a;209.长度最小的字数组 题目分析: 给定一个含有 n 个 正整数 的数组…

数据集笔记:新加坡 地铁(MRT)和轻轨(LRT)票价

数据连接 data.gov.sg 2024 年 12 月 28 日起生效的新加坡地铁票价 该数据集包含 MRT 和 LRT 票价的信息&#xff0c;包括&#xff1a; 票价类型&#xff08;Fare Type&#xff09;&#xff1a;成人票、学生票、老年人票、残障人士票等。适用时间&#xff08;Applicable Tim…

【前端基础】Day 3 CSS-2

目录 1. Emmet语法 1.1 快速生成HTML结构语法 1.2 快速生成CSS样式语法 2. CSS的复合选择器 2.1 后代选择器 2.2 子选择器 2.3 并集选择器 2.4 伪类选择器 2.4.1 链接伪类选择器 2.4.2 focus伪类选择器 2.5 复合选择器总结 3. CSS的元素显示模式 3.1 什么是元素显示…

RabbitMQ操作实战

1.RabbitMQ安装 RabbitMQ Windows 安装、配置、使用 - 小白教程-腾讯云开发者社区-腾讯云下载erlang&#xff1a;http://www.erlang.org/downloads/https://cloud.tencent.com/developer/article/2192340 Windows 10安装RabbitMQ及延时消息插件rabbitmq_delayed_message_exch…

【北京迅为】itop-3568 开发板openharmony鸿蒙烧写及测试-第2章OpenHarmony v3.2-Beta4版本测试

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

stm32hal库寻迹+蓝牙智能车(STM32F103C8T6)

简介: 这个小车的芯片是STM32F103C8T6&#xff0c;其他的芯片也可以照猫画虎,基本配置差不多,要注意的就是,管脚复用,管脚的特殊功能,(这点不用担心,hal库每个管脚的功能都会给你罗列,很方便的.)由于我做的比较简单,只是用到了几个简单外设.主要是由带霍尔编码器电机的车模,电机…

SQL命令详解之操作数据库

操作数据库 SQL是用于管理和操作关系型数据库的标准语言。数据库操作是SQL的核心功能之一&#xff0c;主要用于创建、修改和删除数据库对象&#xff0c;如数据库、表、视图和索引等。以下是SQL中常见的数据库操作命令及其功能简介&#xff1a; 1. 查询数据库 查询所有的数据库…

Go红队开发—编解码工具

文章目录 开启一个项目编解码工具开发Dongle包Base64编解码摩斯密码URL加解密AES加解密 MD5碰撞工具开发 开启一个项目 这作为补充内容&#xff0c;可忽略直接看下面的编解码&#xff1a; 一开始用就按照下面的步骤即可 1.创建一个文件夹&#xff0c;你自己定义名字(建议只用…

Starrocks入门(二)

1、背景&#xff1a;考虑到Starrocks入门这篇文章&#xff0c;安装的是3.0.1版本的SR&#xff0c;参考&#xff1a;Starrocks入门-CSDN博客 但是官网的文档&#xff0c;没有对应3.0.x版本的资料&#xff0c;却有3.2或者3.3或者3.4或者3.1或者2.5版本的资料&#xff0c;不要用较…

SwiftUI之状态管理全解析

文章目录 引言一、`@State`1.1 基本概念1.2 初始化与默认值1.3 注意事项二、`@Binding`2.1 基本概念2.2 初始化与使用2.3 注意事项三、`@ObservedObject`3.1 基本概念3.2 初始化与使用3.3 注意事项四、`@EnvironmentObject`4.1 基本概念4.2 初始化与使用4.3 注意事项五、`@Stat…

Redis 高可用性:如何让你的缓存一直在线,稳定运行?

&#x1f3af; 引言&#xff1a;Redis的高可用性为啥这么重要&#xff1f; 在现代高可用系统中&#xff0c;Redis 是一款不可或缺的分布式缓存与数据库系统。无论是提升访问速度&#xff0c;还是实现数据的高效持久化&#xff0c;Redis 都能轻松搞定。可是&#xff0c;当你把 …

Redis---缓存穿透,雪崩,击穿

文章目录 缓存穿透什么是缓存穿透&#xff1f;缓存穿透情况的处理流程是怎样的&#xff1f;缓存穿透的解决办法缓存无效 key布隆过滤器 缓存雪崩什么是缓存雪崩&#xff1f;缓存雪崩的解决办法 缓存击穿什么是缓存击穿&#xff1f;缓存击穿的解决办法 区别对比 在如今的开发中&…

【定昌Linux系统】部署了java程序,设置开启启动

将代码上传到相应的目录&#xff0c;并且配置了一个.sh的启动脚本文件 文件内容&#xff1a; #!/bin/bash# 指定JAR文件的路径&#xff08;如果JAR文件在当前目录&#xff0c;可以直接使用文件名&#xff09; JAR_FILE"/usr/local/java/xs_luruan_client/lib/xs_luruan_…