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

Linux应用:线程进阶

线程同步之信号量

信号量(Semaphore)是一个整型的计数器,用于控制对共享资源的访问。它通过 PV 操作来实现同步,P 操作将信号量的值减 1,如果值小于 0 则线程阻塞;V 操作将信号量的值加 1,如果有线程在等待则唤醒一个等待的线程。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>sem_t sem;  // 定义信号量void* thread_function(void* arg) {// P操作sem_wait(&sem);printf("子线程进入临界区\n");// 模拟临界区操作sleep(2);printf("子线程离开临界区\n");// V操作sem_post(&sem);return NULL;
}int main() {pthread_t thread;// 初始化信号量,初始值设为1sem_init(&sem, 0, 1);// 创建线程if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {perror("线程创建失败");return 1;}// 主线程等待一段时间sleep(1);// P操作 作用是将信号量的值减 1  值大于0才能减sem_wait(&sem);printf("主线程进入临界区\n");// 模拟临界区操作sleep(2);printf("主线程离开临界区\n");// V操作 使信号量的值加 1sem_post(&sem);// 等待线程结束if (pthread_join(thread, NULL) != 0) {perror("线程等待失败");return 1;}// 销毁信号量sem_destroy(&sem);return 0;
}

sem_t属于信号量类型,sem是所定义的信号量变量。

sem_wait(&sem):这是信号量的 P 操作,其作用是将信号量的值减 1。若信号量的值为 0,线程会被阻塞,直至信号量的值大于 0。
printf(“线程进入临界区\n”);:输出线程进入临界区的信息。
sleep(2);:模拟在临界区内进行的操作,这里让线程休眠 2 秒。
printf(“线程离开临界区\n”);:输出线程离开临界区的信息。
sem_post(&sem):这是信号量的 V 操作,会使信号量的值加 1,同时唤醒可能处于阻塞状态的线程。

pthread_t thread;:定义一个线程标识符。
sem_init(&sem, 0, 1);:对信号量进行初始化,第二个参数为 0 表示该信号量仅在线程间共享,第三个参数 1 为信号量的初始值。
pthread_create(&thread, NULL, thread_function, NULL):创建一个新线程,新线程会执行thread_function函数。
sleep(1);:主线程等待 1 秒,确保新线程有机会运行。
sem_wait(&sem);:主线程执行 P 操作,尝试进入临界区。
printf(“主线程进入临界区\n”);:输出主线程进入临界区的信息。
sleep(2);:模拟主线程在临界区内的操作。
printf(“主线程离开临界区\n”);:输出主线程离开临界区的信息。
sem_post(&sem);:主线程执行 V 操作,离开临界区。
pthread_join(thread, NULL);:主线程等待新线程结束。
sem_destroy(&sem);:销毁信号量,释放相关资源。

在这里插入图片描述
创建了一个新线程,利用信号量实现了主线程和新线程对临界区的互斥访问。信号量的初始值为 1,同一时刻仅允许一个线程进入临界区。通过 P 操作和 V 操作保证了线程安全,防止多个线程同时访问临界区从而引发数据竞争问题。

线程同步之互斥锁

互斥锁(Mutex)是一种特殊的二元信号量(初始值为 1),用于保证在同一时刻只有一个线程能够访问共享资源,也就是一次只有一个线程能够获得锁,其他线程必须等待锁被释放。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  // 定义并初始化互斥锁void* thread_function(void* arg) {// 加锁pthread_mutex_lock(&mutex);printf("线程进入临界区\n");// 模拟临界区操作sleep(2);printf("线程离开临界区\n");// 解锁pthread_mutex_unlock(&mutex);return NULL;
}int main() {pthread_t thread;// 创建线程if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {perror("线程创建失败");return 1;}// 主线程等待一段时间sleep(1);// 加锁pthread_mutex_lock(&mutex);printf("主线程进入临界区\n");// 模拟临界区操作sleep(2);printf("主线程离开临界区\n");// 解锁pthread_mutex_unlock(&mutex);// 等待线程结束if (pthread_join(thread, NULL) != 0) {perror("线程等待失败");return 1;}return 0;
}

在这里插入图片描述
stdio.h:标准输入输出库,提供了像 printf 这样用于输出信息到控制台的函数。
pthread.h:多线程相关的库,包含了创建线程、管理线程和使用互斥锁等操作所需的函数和数据类型。
unistd.h:提供了 sleep 函数,用于让线程暂停执行一段时间。

pthread_mutex_t 是一种数据类型,用于表示互斥锁。
mutex 是定义的互斥锁变量。
PTHREAD_MUTEX_INITIALIZER 是一个宏,用于静态初始化互斥锁,将其设置为初始状态。

pthread_mutex_lock(&mutex):调用该函数尝试获取互斥锁 mutex。如果互斥锁当前未被其他线程持有,调用线程会获取到锁并继续执行后续代码;如果互斥锁已经被其他线程持有,调用线程会被阻塞,直到锁被释放。
printf(“线程进入临界区\n”);:输出信息表明线程已经成功进入临界区。
sleep(2);:模拟线程在临界区内执行一些耗时操作,这里让线程暂停 2 秒。
printf(“线程离开临界区\n”);:输出信息表明线程即将离开临界区。
pthread_mutex_unlock(&mutex):调用该函数释放互斥锁,使得其他等待该锁的线程有机会获取锁并进入临界区。

pthread_t thread;:定义一个 pthread_t 类型的变量 thread,用于存储新创建线程的标识符。
pthread_create(&thread, NULL, thread_function, NULL):创建一个新线程,新线程将执行 thread_function 函数。如果线程创建失败,pthread_create 函数会返回非零值,此时程序会输出错误信息并终止。
sleep(1);:主线程暂停 1 秒,目的是让新创建的线程有机会先运行并尝试获取互斥锁。
pthread_mutex_lock(&mutex):主线程尝试获取互斥锁。如果此时新线程已经持有锁,主线程会被阻塞。
printf(“主线程进入临界区\n”);:输出信息表明主线程已经成功进入临界区。
sleep(2);:模拟主线程在临界区内执行一些耗时操作,暂停 2 秒。
printf(“主线程离开临界区\n”);:输出信息表明主线程即将离开临界区。
pthread_mutex_unlock(&mutex):主线程释放互斥锁。
pthread_join(thread, NULL):主线程等待新创建的线程执行完毕。如果等待过程中出现错误,pthread_join 函数会返回非零值,程序会输出错误信息并终止。

通过创建一个新线程和主线程,利用互斥锁实现了对临界区的互斥访问。互斥锁保证了同一时间只有一个线程能够进入临界区执行操作,避免了多个线程同时访问共享资源可能导致的数据不一致问题。当一个线程进入临界区时,会先获取互斥锁,操作完成后释放锁,使得其他线程可以继续竞争进入临界区。

线程同步之条件变量

条件变量(Condition Variable)用于线程间的同步,它允许一个线程等待某个条件满足后再继续执行。通常与互斥锁一起使用,线程在获取互斥锁后检查条件是否满足,如果不满足则通过条件变量等待,并释放互斥锁;当另一个线程改变了条件后,通过条件变量唤醒等待的线程,等待的线程重新获取互斥锁后继续执行。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int flag = 0;void* thread_function(void* arg) {// 加锁pthread_mutex_lock(&mutex);while (flag == 0) {// 等待条件变量,同时释放互斥锁printf("线程得到锁\n");sleep(1);printf("线程释放锁 1 \n");pthread_cond_wait(&cond, &mutex);printf("线程释放锁 2 \n");}printf("线程被唤醒,条件满足\n");// 解锁pthread_mutex_unlock(&mutex);return NULL;
}int main() {pthread_t thread;// 创建线程if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {perror("线程创建失败");return 1;}// 主线程等待一段时间sleep(2);// 加锁pthread_mutex_lock(&mutex);flag = 1;// 唤醒等待的线程printf("唤醒等待的线程 1\n");pthread_cond_signal(&cond);printf("唤醒等待的线程 2\n");// 解锁pthread_mutex_unlock(&mutex);printf("唤醒等待的线程 3\n");// 等待线程结束if (pthread_join(thread, NULL) != 0) {perror("线程等待失败");return 1;}return 0;
}

在这里插入图片描述
mutex:互斥锁,用于保护共享资源,PTHREAD_MUTEX_INITIALIZER 是一个宏,用于静态初始化互斥锁。
cond:条件变量,用于线程间的同步通信,PTHREAD_COND_INITIALIZER 是一个宏,用于静态初始化条件变量。
flag:共享变量,作为线程间通信的标志,初始值为 0。

pthread_mutex_lock(&mutex):线程进入临界区前加锁,确保同一时间只有一个线程可以访问共享资源。
while (flag == 0):检查共享变量 flag 的值,如果为 0,则线程需要等待条件满足。
pthread_cond_wait(&cond, &mutex):这是一个关键函数,它会做两件事:
释放当前持有的互斥锁 mutex,允许其他线程进入临界区。
阻塞当前线程,直到条件变量 cond 被其他线程发出信号(pthread_cond_signal 或 pthread_cond_broadcast)。
当线程被唤醒后,它会重新获取互斥锁 mutex,继续执行后续代码。
printf(“线程被唤醒,条件满足\n”);:当 flag 变为 1 时,线程被唤醒,输出相应信息。
pthread_mutex_unlock(&mutex):线程离开临界区,释放互斥锁。

pthread_create(&thread, NULL, thread_function, NULL):创建一个新线程,执行 thread_function 函数。
sleep(2):主线程休眠 2 秒,确保新线程有足够的时间进入等待状态。
pthread_mutex_lock(&mutex):主线程进入临界区,加锁。
flag = 1:修改共享变量 flag 的值,表示条件已经满足。
pthread_cond_signal(&cond):发送信号给等待在条件变量 cond 上的线程,唤醒其中一个线程。
pthread_mutex_unlock(&mutex):主线程离开临界区,释放互斥锁。
pthread_join(thread, NULL):主线程等待新线程执行完毕,确保程序正常结束。

通过互斥锁和条件变量实现了线程间的同步。新线程在 flag 为 0 时等待条件满足,主线程在适当的时候修改 flag 的值并发送信号唤醒等待的线程。这样可以避免线程忙等待,提高程序的效率。

相关文章:

Linux应用:线程进阶

线程同步之信号量 信号量&#xff08;Semaphore&#xff09;是一个整型的计数器&#xff0c;用于控制对共享资源的访问。它通过 PV 操作来实现同步&#xff0c;P 操作将信号量的值减 1&#xff0c;如果值小于 0 则线程阻塞&#xff1b;V 操作将信号量的值加 1&#xff0c;如果…...

策略模式 (Strategy)

策略模式 (Strategy) 应用场景&#xff1a;用于处理不同的任务配置参数。在你的任务中&#xff0c;可能会有不同的任务类型&#xff0c;每个任务类型可能有不同的单位&#xff08;比如米、毫米&#xff09;或不同的处理方式。策略模式可以让你根据不同的任务类型选择不同的处理…...

【YOLOv8】YOLOv8改进系列(10)----替换主干网络之UniRepLKNet

主页&#xff1a;HABUO&#x1f341;主页&#xff1a;HABUO &#x1f341;YOLOv8入门改进专栏&#x1f341; &#x1f341;如果再也不能见到你&#xff0c;祝你早安&#xff0c;午安&#xff0c;晚安&#x1f341; 【YOLOv8改进系列】&#xff1a; YOLOv8改进系列&#xff0…...

mathtype一些用法总结

1.一个是公式旁边加入||&#xff0c;一般使用键盘直接打入的会比较小&#xff0c;mathtype中的会好看很多&#xff0c;打开这个栏目&#xff0c;会看到有很多。 2.另外是带^符号&#xff0c;在字符上面带没有办法直接带&#xff0c;所以可以在mathtype中先加帽子&#xff0c;然…...

1、SQL注入攻击的防范

原文地址: SQL注入攻击的防范 更多内容请关注&#xff1a;代码安全 PHP安全编码——书写安全的代码 1、SQL注入攻击的防范 提问 问题1&#xff1a;什么是SQL注入攻击&#xff1f; 问题2&#xff1a;有几种简单方法防范SQL注入攻击&#xff1f; 问题3&#xff1a;mys…...

核心知识——论文总结

引入 本文我们会针对论文中的核心内容进行总结&#xff0c;加深小伙伴对于Spark的理解。而通过Spark的论文&#xff0c;重点需要掌握理解如下内容&#xff1a; Spark 里核心的 RDD 是一个什么概念&#xff0c;它是通过什么方式来优化分布式数据处理的&#xff0c;它的设计思路…...

HTTP 核心知识点整理

1. HTTP 基础 ​定义&#xff1a;HTTP&#xff08;HyperText Transfer Protocol&#xff09;是应用层协议&#xff0c;基于 ​请求-响应模型&#xff0c;用于客户端&#xff08;浏览器&#xff09;与服务器之间的通信。​特点&#xff1a; ​无状态&#xff1a;每次请求独立&a…...

什么是矩阵账号

矩阵账号是指在同一平台或多个平台上&#xff0c;围绕同一品牌或个人&#xff0c;创建的多个相互关联、协同工作的账号组合。这些账号虽然独立&#xff0c;但在内容定位和运营策略上有所区分&#xff0c;同时又相互引流&#xff0c;共同形成一个网络结构&#xff0c;类似于矩阵…...

【6】VS Code 新建上位机项目---项目分层

【6】VS Code 新建上位机项目---项目分层 1 项目分层(layer)2 项目分层实现数据插入SQL3 项目分层实现 (实体类封装参数)4 项目分层的实现SQL查询数据1 项目分层(layer) 表示层(UI):与用户交互使用。比如按钮,输入信息等;业务层(BLL):传递数据,业务逻辑。根据用户需…...

EspressoSample深度解析:在CircleCI上高效运行Android UI测试

项目背景与简介 EspressoSample项目位于GitHub上的circleci/EspressoSample仓库&#xff0c;该项目旨在展示如何在CircleCI平台上配置和使用Espresso进行Android应用的UI测试。 项目结构与环境准备 项目结构 EspressoSample项目遵循典型的Android项目结构&#xff0c;包含a…...

【每日论文】MetaSpatial: Reinforcing 3D Spatial Reasoning in VLMs for the Metaverse

下载PDF或查看论文&#xff0c;请点击&#xff1a; LlamaFactory - huggingface daily paper - 每日论文解读 | LlamaFactory | LlamaFactory探索LlamaFactory&#xff0c;为你解读AI前沿技术文章&#xff0c;快速掌握最新技术动态https://www.llamafactory.cn/daily-paper/de…...

mac m4 Homebrew安装MySQL 8.0

1.使用Homebrew安装MySQL8 在终端中输入以下命令来安装MySQL8&#xff1a; brew install mysql8.0 安装完成后&#xff0c;您可以通过以下命令来验证MySQL是否已成功安装&#xff1a; 2.配置mysql环境变量 find / -name mysql 2>/dev/null #找到mysql的安装位置 cd /op…...

Java关于多态

多态 字面意思&#xff1a;对象的多种形态。 Student(子类)<-Person(父类)->Teacher(子类) Student snew Student(); 学生形态 对象 代表用new创建一个学生对象赋值给Student 类型&#xff0c;代表Student类型(学生对象)现在是学生形态。 有了多态之后&#xff…...

K8S学习之基础四十六:k8s中部署Kibana

部署kibana组件 上传kibina镜像到harbor 部署kibana组件&#xff0c;包括svc和deplomentvi kibana.yaml apiVersion: v1 kind: Service metadata:name: kibananamespace: kube-logginglabels:app: kibana spec:ports:- port: 5601selector:app: kibana --- apiVersion: apps/…...

如何快速对比两个不同的excel文件中的单元格的数据是否完全相同 并把不同的单元格的背景颜色更改为红色?

要快速对比两个不同的Excel文件中的单元格数据是否完全相同&#xff0c;并将不同的单元格背景颜色更改为红色&#xff0c;可以使用Excel的以下几种方法&#xff1a; 方法一&#xff1a;使用条件格式 打开两个Excel文件。将一个文件的内容复制到另一个文件的新工作表中&#x…...

基于Python+LanceDB实战向量搜索

本篇实战演示向量搜索的实现和示例。 预期效果 给出一个查询的字符串&#xff0c;通过向量搜索&#xff0c;在下面三个语句中搜索出关联性最大的那句。 "熊猫是中国的国宝&#xff0c;主要栖息在四川山区。","长城是古代中国建造的军事防御工事&#xff0c;全…...

多路转接epoll

目录 一、为什么epoll最高效&#xff1f; 二、epoll的三个系统调用 三、理解epoll模型 四、epoll的优点 五、epoll的使用示例 六、epoll的工作模式 ET模式和LT模式的对比 七、epoll的使用场景 总结 一、为什么epoll最高效&#xff1f; 按照 man 手册的…...

AI编程工具哪家强?对比Cusor、Copilot、Cline

前言 AI最先革谁的命&#xff1f;刚毕业参加工作的那个时候就在想是否可以开发一个程序让它自己写代码&#xff0c;在那个遥远的年代&#xff0c;这种想法仿佛就是天方夜谭。但是今天大模型的出现让理想成为了现实。回答前面的问题&#xff0c;AI最先革谁的命&#xff0c;最聪…...

[FPGA基础学习]实现流水灯与按键暂停

FPGA实现LED流水灯 1.vscode的安装和使用 vscode下载 Visual Studio Code - Code Editing. Redefined vscode插件&#xff08;Verilog-HDL/SystemVerilog&#xff09;下载 quartus绑定vscode 2.用6个LED完成周期为1秒的跑马灯效果 流水灯模块设计 时钟输入 DE2-115开发板…...

刷题记录(LeetCode 994.腐烂的橘子)

在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b;值 1 代表新鲜橘子&#xff1b;值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。 返回 直到单元格中没有…...

ECharts折线图源码合集1(共18个自定义图表),附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我整理了18个自定义折线图图表&#xff0c;不仅对每个图表代码进行了精简优化&#xff0c;剥离冗余配置项&#xff0c;…...

SQL小菜之TOP N查找问题

前言 SQL的编写是后端面试中非常常见&#xff0c;其中TOP N查找问题也是高频出现的问题&#xff0c;今天我们来看两道SQL TOPN问题。 问题 我们有一张雇员表Employee&#xff1a; CREATE TABLE Employee (id int DEFAULT NULL,salary int DEFAULT NULL,department varchar(…...

蓝桥杯 临时抱佛脚 之 二分答案法与相关题目

二分答案法&#xff08;利用二分法查找区间的左右端点&#xff09; &#xff08;1&#xff09;估计 最终答案可能得范围 是什么 &#xff08;2&#xff09;分析 问题的答案 和 给定条件 之间的单调性&#xff0c;大部分时候只需要用到 自然智慧 &#xff08;3&#xff09;建…...

Css环形旋转立体感动画

Css环形旋转立体感动画 index.html <!DOCTYPE html> <html lang"en" > <head><meta charset"UTF-8"><title>Css环形旋转立体感动画</title><link rel"stylesheet" href"./style.css">&l…...

音乐极客指南:Melody高音质私有云音乐平台本地部署方案

文章目录 前言1. 添加镜像源2. 本地部署Melody3. 本地访问与使用演示4. 安装内网穿透5. 配置Melody公网地址6. 配置固定公网地址 前言 嘿&#xff0c;各位音乐爱好者们&#xff01;今天我要带大家玩个大招——在香橙派Zero3上搭建你的专属在线音乐平台&#xff0c;还能通过cpo…...

Microi吾码界面设计引擎之基础组件用法大全【内置组件篇·中】

&#x1f380;&#x1f380;&#x1f380; microi-pageengine 界面引擎系列 &#x1f380;&#x1f380;&#x1f380; 一、Microi吾码&#xff1a;一款高效、灵活的低代码开发开源框架【低代码框架】 二、Vue3项目快速集成界面引擎 三、Vue3 界面设计插件 microi-pageengine …...

# WebSocket 与 Socket.IO 对比与优化

核心概念对比 WebSocket 协议性质&#xff1a;HTML5 提供的全双工通信协议 (RFC 6455)连接方式&#xff1a;基于 TCP 的低层协议通信模式&#xff1a;持久化连接&#xff0c;服务端可主动推送协议升级&#xff1a;通过 HTTP 101 状态码切换协议 Socket.IO 协议性质&#xf…...

vue3中,route4,获取当前页面路由的问题

首先应用场景如下&#xff1a; 在main.js里面&#xff0c;引入的是路由的配置文件&#xff0c;如下&#xff1a; import {router} from /router; app.use(router); 路由配置文件router.js如下&#xff1a; import { createRouter, createWebHistory } from vue-router; imp…...

python将整个txt文件写入excel的一个单元格?

要将整个txt文件写入Excel的一个单元格&#xff0c;可以使用Python的openpyxl库来实现。以下是一个简单的示例代码&#xff1a; from openpyxl import Workbook# 读取txt文件内容 with open(file.txt, r) as file:txt_content file.read()# 创建一个新的Excel工作簿 wb Work…...

日志2333

Pss-9 这一关考察的是时间盲注 先练习几个常见命令语句&#xff1a; select sleep(5);--延迟5s输出结果 if &#xff08;1>0,ture,false&#xff09;;--输出‘ture’ /if &#xff08;1<0,ture,false&#xff09;;--输出‘false’ select ascii()/select ord()返回字…...

用Deepseek写扫雷uniapp小游戏

扫雷作为Windows系统自带的经典小游戏&#xff0c;承载了许多人的童年回忆。本文将详细介绍如何使用Uniapp框架从零开始实现一个完整的扫雷游戏&#xff0c;包含核心算法、交互设计和状态管理。无论你是Uniapp初学者还是有一定经验的开发者&#xff0c;都能从本文中获得启发。 …...

C++中的异常和智能指针

一、C中的异常 1.1C语言中关于错误的处理&#xff08;回顾&#xff09; 1.1.1处理一&#xff1a;文件中的错误码&#xff0c;错误信息 C语言中&#xff0c;文件打开成功则返回地址&#xff0c;不成功返回0 FILE* foutfopen("Test.txt","r"); cout<&…...

Selenium 简单入门操作示例

最简单的 Selenium 示例&#xff08;Python版&#xff09; 下面是一个完整的、最简单的 Selenium 操作示例&#xff0c;带你快速上手&#xff1a; from selenium import webdriver from selenium.webdriver.common.by import By import time# 1. 启动浏览器&#xff08;这里使…...

6.1 模拟专题:LeetCode 1576. 替换所有的问号

1. 题目链接 LeetCode 1576. 替换所有的问号 2. 题目描述 给定一个仅包含小写字母和问号 ? 的字符串 s&#xff0c;要求将所有 ? 替换为任意小写字母&#xff0c;使得替换后的字符串中 没有相邻的两个字符相同。 示例&#xff1a; 输入&#xff1a;s "?zs" →…...

前端知识点---用正则表达式判断邮箱(javascript)

// 全面的正则&#xff08;兼容大多数情况&#xff09; const emailRegex /^[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.[a-zA-Z]{2,}$/;// 或直接使用浏览器内置验证 <input type"email" required>/&#xff1a;正则表达式的起始和结束标志。 ^&#xff1a;匹配字符串的…...

深度剖析 Spring 源码 性能优化:核心原理与最佳实践

深度剖析 Spring 源码 & 性能优化&#xff1a;核心原理与最佳实践 &#x1f680; Spring 框架 作为 Java 生态的核心技术&#xff0c;广泛应用于企业级开发。但很多开发者只会“用”Spring&#xff0c;而不深入其内部原理&#xff0c;导致无法高效排查问题 & 进行性能优…...

Axure RP9教程 :轮播图(动态面板) | 头部锁定

文章目录 引言I 轮播图操作步骤在画布中添加一个动态面板设置面板状态II 头部锁定将头部区域选中,右键组合或用Ctrl+G快捷键;将组合的头部区域,右键创建动态面板;引言 动态面板的功能十分强大,比如:拥有独立的内部坐标系,有多个状态; Banner的案例中会用到动态面板多个…...

rabbitmq承接MES客户端服务器

文章目录 背景整体架构概述方案详细步骤1. 数据库选型与搭建2. 设备端数据上传至数据库3. 搭建 RabbitMQ 服务器4. 数据同步模块&#xff08;数据库到 RabbitMQ&#xff09;5. MES 服务器从 RabbitMQ 接收数据6. 指令接收模块&#xff08;RabbitMQ 到设备端&#xff09; 7. MES…...

重学vue3(三):vue3基本语法及使用

组合式 API是vue3 的核心特性&#xff0c;替代 Vue2 的选项式 API&#xff0c;强调逻辑复用和代码组织。基本语法如下&#xff1a; <script setup> import { ref, reactive, computed, onMounted } from vue;// 1. 响应式数据 const count ref(0); // 基本类…...

算法 | 麻雀搜索算法原理,公式,改进算法综述,应用场景及matlab完整代码

一、麻雀搜索算法(SSA)原理 1. 算法基础 麻雀搜索算法(Sparrow Search Algorithm, SSA)是2020年提出的一种群体智能优化算法,灵感来源于麻雀群体的觅食与反捕食行为。算法将麻雀分为三类角色:发现者(Producer):适应度最高,负责探索全局最优区域;加入者(Follower)…...

0322-数据库与前后端的连接、数据库表的增删改查

前端 <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>Insert title here</title> <script srcjs/jquery-3.7.1.min.js></script> <script> //jquaryajax发起请求 //传参形式不同 post用data{}…...

详细介绍Qt中用于断言的宏 Q_ASSERT

Q_ASSERT 是 Qt 框架中用于调试的核心宏之一&#xff0c;其作用类似于标准 C/C 的 assert&#xff0c;但针对 Qt 的特性进行了优化。它用于在开发阶段验证程序的逻辑正确性&#xff0c;帮助开发者快速定位潜在的错误。 1.基本用法 Q_ASSERT(condition);功能&#xff1a;在调试…...

基于Python的自然语言处理系列(60):使用 LangChain 构建 Multi-Vector Retriever 进行文档检索

在 NLP 和 AI 领域&#xff0c;基于嵌入&#xff08;Embeddings&#xff09;进行文档检索已成为一种高效的解决方案。本文介绍如何使用 LangChain 构建 Multi-Vector Retriever&#xff0c;实现对长文档的分块索引和高效检索。 1. 环境准备 首先&#xff0c;我们需要安装相关…...

Dify 部署指南-离线版

Docker 部署 1、 访问 Docker 官网 (https://www.docker.com/) 获取安装包。 2、 上传 Docker 安装包 3、 进入解压目录&#xff0c;执行解压命令 tar xzvf docker-28、0.2、tgz4、 将解压文件中的 Docker 相关文件移动到 /usr/bin/ 目录 sudo cp docker/* /usr/bin/5、 创建…...

解决 Element UI 嵌套弹窗的状态管理问题!!!

解决 Element UI 嵌套弹窗的状态管理问题 &#x1f527; 问题描述 ❓ 在使用 Element UI 开发一个多层嵌套弹窗功能时&#xff0c;遇到了以下问题&#xff1a; 弹窗只能打开一次&#xff0c;第二次点击无法打开 &#x1f6ab;收到 Vue 警告&#xff1a;避免直接修改 prop 值…...

基于STM32单片机的智能手环/音乐播放/语音识别

基于STM32单片机的智能手环/音乐播放/语音识别 持续更新&#xff0c;欢迎关注!!! ** 基于STM32单片机的智能手环/音乐播放/语音识别 ** 21世纪&#xff0c;社会高速发展&#xff0c;生活物质越来越丰富&#xff0c;随着科技的进步&#xff0c;智能化成为了人们关注的焦点&am…...

NFC 智能门锁全栈解决方案:移动端、服务器、Web 管理平台

目录 一、系统整体架构 二、移动端 APP 开发 2.1 开发环境与基础准备 2.2 主要功能模块 2.3 示例代码&#xff08;Android/Kotlin 简化示例&#xff09; 三、后台服务开发 3.1 环境准备 3.2 主要功能 3.3 示例代码&#xff08;Node.js Express 简化示例&#xff09; …...

使用 Python 开发 MCP Server 及 Inspector 工具详解

使用 Python 开发 MCP Server 及 Inspector 工具详解 前言 模型上下文协议 (Model Context Protocol, MCP) 是一种新兴的协议&#xff0c;旨在让大型语言模型 (LLM) 更容易地与外部工具和服务集成。本文将介绍如何使用 Python 开发一个 MCP Server&#xff0c;并详细讲解如何使…...

论坛系统测试报告

一、项目背景 为论坛系统项目设计并进行自动化测试。论坛系统由六个页面构成&#xff1a;用户登录页、用户注册页、个人中心页面、我的帖子页面、帖子编辑页、帖子列表页以及帖子详情页。 通过使用selenium工具来定位到web中的元素&#xff0c;对获取到的元素进行自动化测试等操…...

Android一个APP里面最少有几个线程

Android应用启动时,默认会创建一个进程,该进程中最少包含5个系统自动创建的线程,具体如下: Main线程(主线程/UI线程) 负责处理用户交互、UI更新等核心操作,所有与界面相关的逻辑必须在此线程执行。若在此线程执行耗时操作(如网络请求),会导致界面卡顿甚至触发ANR(应…...