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

学懂C++(三十四):深入详解 C++ 高级多线程编程技术中的并发设计模式

引言

        在现代软件开发中,多线程编程已成为提升性能和响应能力的重要手段。设计模式为解决并发问题提供了有效的解决方案。本文将探讨常见的并发设计模式,包括生产者-消费者模式、读者-写者模式、单例模式、帧-工作者模式以及Future-Task模式,并为每个示例提供详细的注释和解析,以帮助读者更好地理解其实现原理。

1. 生产者-消费者模式

1.1 概念

        生产者-消费者模式涉及两个角色:生产者和消费者。生产者负责生成数据并将其放入缓冲区,而消费者则从缓冲区中取出数据进行处理。此模式的关键在于协调生产者和消费者之间的工作,以避免竞态条件和资源浪费。

1.2 示例及解析

以下是一个简单的生产者-消费者模式的实现:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <chrono>// 定义一个线程安全的缓冲区
std::queue<int> buffer; // 用于存放生产的数据
const unsigned int maxBufferSize = 5; // 定义缓冲区的最大大小
std::mutex mtx; // 用于保护缓冲区的互斥锁
std::condition_variable cv; // 用于条件变量通知// 生产者线程函数
void producer(int id) {for (int i = 0; i < 10; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟生产过程std::unique_lock<std::mutex> lock(mtx); // 锁定缓冲区// 等待缓冲区有空间cv.wait(lock, [] { return buffer.size() < maxBufferSize; });buffer.push(i); // 生产数据std::cout << "Producer " << id << " produced: " << i << std::endl;cv.notify_all(); // 通知消费者有新数据可用}
}// 消费者线程函数
void consumer(int id) {for (int i = 0; i < 10; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(150)); // 模拟消费过程std::unique_lock<std::mutex> lock(mtx); // 锁定缓冲区// 等待缓冲区有数据cv.wait(lock, [] { return !buffer.empty(); });int value = buffer.front(); // 取出数据buffer.pop(); // 移除数据std::cout << "Consumer " << id << " consumed: " << value << std::endl;cv.notify_all(); // 通知生产者有空间可以生产}
}int main() {std::thread p1(producer, 1); // 创建生产者线程std::thread c1(consumer, 1); // 创建消费者线程p1.join(); // 等待生产者线程结束c1.join(); // 等待消费者线程结束return 0;
}

1.3 运行结果分析

在这个示例中,生产者和消费者线程通过互斥锁和条件变量进行同步,确保了对共享缓冲区的安全访问。生产者在缓冲区满时等待,而消费者在缓冲区空时等待。

2. 读者-写者模式

2.1 概念

读者-写者模式允许多个读者并行访问资源,但在写者访问资源时,所有读者和其他写者必须被阻塞。这种模式适用于读操作远远多于写操作的场景。

2.2 示例及解析

以下是一个简单的读者-写者模式的实现:

#include <iostream>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <chrono>std::shared_mutex rwMutex; // 读写锁
int sharedData = 0; // 共享数据// 读者线程函数
void reader(int id) {for (int i = 0; i < 5; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟读操作rwMutex.lock_shared(); // 获取共享锁std::cout << "Reader " << id << " read: " << sharedData << std::endl; // 输出共享数据rwMutex.unlock_shared(); // 释放共享锁}
}// 写者线程函数
void writer(int id) {for (int i = 0; i < 5; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(200)); // 模拟写操作rwMutex.lock(); // 获取独占锁sharedData++; // 修改共享数据std::cout << "Writer " << id << " wrote: " << sharedData << std::endl; // 输出更新后的数据rwMutex.unlock(); // 释放独占锁}
}int main() {std::thread r1(reader, 1); // 创建读者线程std::thread r2(reader, 2); // 创建另一个读者线程std::thread w1(writer, 1); // 创建写者线程r1.join(); // 等待读者线程结束r2.join(); // 等待读者线程结束w1.join(); // 等待写者线程结束return 0;
}

2.3 运行结果分析

在这个示例中,多个读者可以同时读取数据,而在写者写入数据时,读者会被阻塞,提高了性能。

3. 单例模式

3.1 概念

单例模式确保一个类仅有一个实例,并提供全局访问点。在线程安全的上下文中,特别需要确保在多线程环境下创建实例的安全性。

3.2 示例及解析

以下是一个线程安全的单例模式实现示例:

#include <iostream>
#include <mutex>// 单例类定义
class Singleton {
public:// 获取单例实例static Singleton& getInstance() {std::call_once(initFlag, []() { // 确保单例只被初始化一次instance.reset(new Singleton());});return *instance; // 返回单例实例}void displayMessage() {std::cout << "Singleton Instance Address: " << this << std::endl; // 输出实例地址}private:Singleton() = default; // 私有构造函数static std::unique_ptr<Singleton> instance; // 存储单例实例的智能指针static std::once_flag initFlag; // 一次性标志
};// 静态成员初始化
std::unique_ptr<Singleton> Singleton::instance;
std::once_flag Singleton::initFlag;int main() {std::thread t1([]() { Singleton::getInstance().displayMessage(); });std::thread t2([]() { Singleton::getInstance().displayMessage(); });t1.join(); // 等待线程t1结束t2.join(); // 等待线程t2结束return 0;
}

3.3 运行结果分析

运行结果显示无论创建多少线程,单例实例只会创建一个,保证了线程安全。

4. 帧-工作者模式

4.1 概念

帧-工作者模式是一种常见的并发设计模式,适用于需要将大量任务分配给多个工作线程处理的场景。通过将任务分成较小的块,将这些块分配给多个工作线程,可以实现高效的并发处理。

4.2 示例及解析

以下是帧-工作者模式的简单实现:

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>std::mutex mtx; // 用于保护输出的互斥锁// 工作线程函数
void worker(int id, int start, int end) {for (int i = start; i < end; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(50)); // 模拟工作std::lock_guard<std::mutex> lock(mtx); // 锁定互斥锁std::cout << "Worker " << id << " processing: " << i << std::endl; // 输出处理信息}
}int main() {const int totalWork = 20; // 总工作量const int numWorkers = 4; // 工作线程数量std::vector<std::thread> workers; // 存储线程的向量int workPerThread = totalWork / numWorkers; // 每个线程处理的工作量for (int i = 0; i < numWorkers; ++i) {// 创建工作线程,分配不同的任务块workers.emplace_back(worker, i + 1, i * workPerThread, (i + 1) * workPerThread);}for (auto& worker : workers) {worker.join(); // 等待所有工作线程结束}return 0;
}

4.3 运行结果分析

在该示例中,多个工作线程可以并行处理不同的任务块,提升了效率。

5. Future-Task 模式

5.1 概念

Future-Task模式是一种用于异步编程的设计模式,允许任务在后台异步执行,并在需要时获取结果。这种模式通常与线程池结合使用,以提高资源利用率。

5.2 示例及解析

以下是 Future-Task 模式的实现示例:

#include <iostream>
#include <future>
#include <thread>
#include <chrono>// 异步任务
int asyncTask(int id) {std::this_thread::sleep_for(std::chrono::milliseconds(100 * id)); // 模拟耗时任务return id * 2; // 返回计算结果
}int main() {// 使用 std::async 启动异步任务std::future<int> fut1 = std::async(std::launch::async, asyncTask, 1);std::future<int> fut2 = std::async(std::launch::async, asyncTask, 2);// 获取结果并输出std::cout << "Result from task 1: " << fut1.get() << std::endl; // 阻塞等待 task 1 完成std::cout << "Result from task 2: " << fut2.get() << std::endl; // 阻塞等待 task 2 完成return 0;
}

5.3 运行结果分析

在这个示例中,两个任务在后台异步执行,主线程可以在等待结果的同时继续处理其他逻辑。

6. 核心点总结与技术精髓

6.1 设计模式的核心点

  • 生产者-消费者模式:利用互斥锁和条件变量保证缓冲区的安全访问,避免竞争条件。
  • 读者-写者模式:允许多个读者并发访问,确保写者访问时的独占性,适用读多写少的场景。
  • 单例模式:确保全局只有一个实例,并提供线程安全的访问方式,适合需要共享资源的情况。
  • 帧-工作者模式:将工作分配给多个线程,提升处理效率,适合大规模并行处理。
  • Future-Task模式:支持异步执行和结果获取,通过将任务放入后台执行来优化资源利用率。

7. 结语

        掌握并发设计模式是实现高效、多线程程序的关键。通过合理的设计和实现,我们能够有效地解决并发问题,提高程序的性能和可靠性。希望本文能够为您在 C++ 的多线程编程中提供有价值的参考和指导。

上一篇:学懂C++(三十三):深入详解 C++ 高级多线程编程技术中的并发数据结构

下一篇:学懂C++(三十五):深入详解C++ 多线程编程性能优化 

相关文章:

学懂C++(三十四):深入详解 C++ 高级多线程编程技术中的并发设计模式

引言 在现代软件开发中&#xff0c;多线程编程已成为提升性能和响应能力的重要手段。设计模式为解决并发问题提供了有效的解决方案。本文将探讨常见的并发设计模式&#xff0c;包括生产者-消费者模式、读者-写者模式、单例模式、帧-工作者模式以及Future-Task模式&#xff0c;并…...

大数据产业链图谱_产业链全景图_大数据行业市场分析

数据作为新型生产要素&#xff0c;是数字化、网络化、智能化的基础&#xff0c;已快速融入生产、分配、流通、消费和社会服务管理等各环节&#xff0c;影响着千行百业&#xff0c;推动着我国数字经济的蓬勃发展。 大数据又称巨量数据、海量数据&#xff0c;是由数量巨大、结构…...

photonserver 部署相关教程

Photon Server 是 Exit Games 开发的高性能、可扩展的多人游戏服务器框架。部署 Photon Server 需要一些基础的服务器管理知识和配置技巧。以下是一个基本的部署教程&#xff0c;帮助你将 Photon Server 部署在 Windows 服务器上。 目录 1. 下载并安装 Photon Server 2. 配置…...

GEE训练:sentinel-1数据的投影、显示和导出

函数 projection() Returns the default projection of an Image. Throws an error if the bands of the image dont all have the same projection. 返回图像的默认投影。如果图像带的投影不一致,则会抛出错误。 Arguments: this:image (Image): The image from which …...

后端学习笔记(七)--MyBatis参数传递

5.MyBatis参数传递 ​ *MyBatis接口方法中可以接收各种各样的参数&#xff0c;MyBatis底层对于这些参数进行不同的封装处理方式 ​ *单个参数&#xff1a; 1.POJO类型&#xff1a;直接使用&#xff0c;属性名和参数占位符名称一致 2.Map集合&#xff1a;直接使用&#xff0c;…...

uniapp 网络请求自动处理loading

文章目录 背景整理思路V1版本V2版本V3版本 背景 最近在写uniapp&#xff0c;发现执行网络请求的时候经常要处理Loading效果。 比如&#xff0c;在发送网络请求之前&#xff0c;触发Loadng&#xff1b;无论请求成功还是失败都要关闭Loading&#xff1b;请求失败的时候我们还要…...

【Solidity】函数的使用

构造函数 构造函数仅在部署合约时调用一次&#xff0c;它的作用主要是初始化一些状态变量。 contract Demo {address public owner;uint public num;constructor(uint _num) {owner msg.sender;num _num;} }函数装饰器 函数装饰器可以在函数执行之前或之后插入代码逻辑&am…...

详解golang内存管理

介绍 要搞明白 Go 语言的内存管理,就必须先理解操作系统以及机器硬件是如何管理内存的。因为 Go 语言的内部机制是建立在这个基础之上的,它的设计,本质上就是尽可能的会发挥操作系统层面的优势,而避开导致低效情况。 操作系统内存管理 其实现在计算机内存管理的方式都是…...

C++ 线程 一些同步方式

C 线程一些同步方式 1.互斥锁&#xff08;Mutex&#xff09;2. 读写锁&#xff08;Reader-Writer Lock&#xff09;3. 信号量&#xff08;Semaphore&#xff09;4. 原子操作&#xff08;Atomic&#xff09;5. 屏障&#xff08;Barrier&#xff09;6. 条件变量&#xff08;Condi…...

【开发语言】编译型语言和解释性语言有啥区别?

作为一名从业多年的程序员,对于编译型语言和解释型语言之间的区别有着深入的理解。这两种类型的编程语言在将源代码转换成可执行代码的过程中采用了不同的机制,这导致了它们在执行效率、跨平台性、安全性以及开发效率等方面存在一些差异。 编译型语言(Compiled Languages)…...

将A服务器上指定文件夹中的文件,批量同步到B服务器上

需求&#xff1a;最近有一个需求&#xff0c;需要定期将A服务器上的PDF文件&#xff0c;同步到B服务器上&#xff0c;于是便写个脚本记录一下&#xff01; 下面是使用Python3脚本实现的方法 import os import paramikodef copy_pdf_files(source_ip, source_user, source_pas…...

2024.8.17

130124202408171002 DATE #:20240817 ITEM #:DOC WEEK #:SATURDAY DAIL #:捌月拾肆 TAGS < BGM "快哉风 -- 黄金玉米王" > < theme oi-language > < theme oi-graph theory > < [空] > < [空] >取次花丛懒回顾&#xff0c;半缘修道…...

十分钟搭建一个RTMP服务器

使用SRS搭建RTMP服务器 如果您需要搭建一个RTMP服务器&#xff0c;您可以使用SRS&#xff08;Simple-RTMP-Server&#xff09;来完成此任务。SRS是一个开源的RTMP服务器下面是一个简单的步骤指南&#xff1a; 获取srs srs官⽹&#xff1a;https://github.com/ossrs/srs 码云…...

Spring Boot解决循环注入问题

Spring Boot解决循环依赖注入问题 代码问题回显启动错误日志解决方案&#xff1a;使用事件驱动或通过 ApplicationContext 手动获取 Bean1. 事件驱动设计2. 使用 ApplicationContext 手动获取 Bean3. 拆分逻辑 总结 代码问题回显 现有代码1 在InterestService中依赖MemberInte…...

《数据挖掘》期末考核重点

1.数据预处理的目的与形式 数据预处理的目的是提供干净&#xff0c;简洁&#xff0c;准确的数据&#xff0c;以达到简化模型和提高算法泛化能力的目的&#xff0c;使挖掘过程更有效&#xff0c;更容易&#xff0c;提高挖掘效率和准确性。 2.数据预处理的形式 数据清理&#…...

Golang | Leetcode Golang题解之第334题递增的三元子序列

题目&#xff1a; 题解&#xff1a; func increasingTriplet(nums []int) bool {n : len(nums)if n < 3 {return false}first, second : nums[0], math.MaxInt32for i : 1; i < n; i {num : nums[i]if num > second {return true} else if num > first {second n…...

HarmonyOs编写一个案例实现一个照片选择(阶段进阶 四种需求 逐一完善)

需求1. .实现照片选择 并将选择好的照片展示出来 import { GoodItem } from ../06/modules;Entry Component struct PhotoPage {State message: string 实现一个相册;State List: GoodItem[] [{goods_name: dsfjlsjkfsf,goods_price: 100,goods_img: https://img1.baidu.com…...

洗衣机洗衣服一些知识

01智能:按衣物多少自动调节合适水位的标准洗涤程序 (需要30分钟时间) 02:大物:较大,较厚的衣服洗涤 03:轻柔:毛织品或内衣洗涤 04:快速:少量清污衣服洗涤 (13分钟) 05:浸泡:先浸泡一段时间再洗涤 06:单洗:只洗衣不脱水 07:单脱:只脱水不洗衣 08:洁桶:清洁洗衣桶 准备工作: (1)…...

探索文件系统:高效、可靠的文件管理与访问机制

文件系统的功能规划 内存就像是一个书包&#xff0c;容量有限&#xff0c;只能带着一部分东西。而图书馆则是一个专门存储和管理文件的地方&#xff0c;拥有更大的容量&#xff0c;并且可以永久保存文件。为了能够快速找到需要的文件&#xff0c;我们需要有一个书单来记录每本…...

启程与远征Ⅸ--优化生成式人工智能以满足业务需求的框架

生成类似人类的文本和语音曾经只存在于科幻小说中。但 GPT-3 和 PaLM 等大型语言模型 (LLM) 的快速发展让这一愿景更接近现实&#xff0c;解锁了从聊天机器人到内容创作等一系列有前景的商业应用。 然而&#xff0c;通用基础模型往往无法满足行业用例的需求。企业对其生成式 A…...

canal数据同步工具介绍与应用

canal服务 canal介绍canal版本与环境canal 服务集canal应用场景&#xff1a; canal常见问题xml配置问题连接认证问题jar版本问题连接问题 canal介绍 ‌1、Canal是‌阿里巴巴开源的‌MySQL增量数据订阅和消费工具&#xff0c;通过模拟MySQL的‌slave与‌master交互&#xff0c;捕…...

ubuntu18.04 设置静态地址

修改配置文件 sudo vim /etc/netplan/01-network-manager-all.yaml 代码如下&#xff1a; network: version: 2 renderer: NetworkManager ethernets: ens33: # 配置的网卡名称&#xff0c;可以使用ifconfig -a查看本机的网卡 dhcp4: no # 关闭动态IP设置 …...

jira敏捷开发管理工具视频教程Confluence工作流协同开发(2024)

正文&#xff1a; 随着Jira敏捷开发方法论的普及&#xff0c;Jira已经成为全球软件开发团队管理项目、任务和问题的首选工具。为了帮助团队更好地掌握Jira的核心功能&#xff0c;精心准备了一套全面开发技术及案例视频教程——《Jira敏捷开发管理工具视频教程Confluenc…...

【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法

文章目录 ServerSocket构造方法方法 Socket构造方法方法 回显服务器&#xff08;Echo Server&#xff09;1. 构造方法2. 建立连接processConnection 方法的创建1. 读取请求并解析2. 根据请求计算响应3. 把响应写回给客户端 3. 完整代码 客户端&#xff08;Echo Client&#xff…...

Python知识点:如何使用Boto3进行AWS服务管理

使用 boto3 来管理 AWS 服务是一个非常强大的方式&#xff0c;因为 boto3 是 AWS 提供的官方 Python SDK。下面是使用 boto3 管理 AWS 服务的基本步骤&#xff0c;包括设置、操作和常见的 AWS 服务示例。 1. 安装 boto3 首先&#xff0c;确保你已经安装了 boto3。可以使用 pi…...

Java - 正则表达式

Java 提供了 java.util.regex 包&#xff0c;它包含了 Pattern 和 Matcher 类&#xff0c;用于处理正则表达式的匹配操作。 正则表达式的模式 正则表达式的模式可以包括以下内容&#xff1a; 字面值字符&#xff1a;例如字母、数字、空格等&#xff0c;可以直接匹配它们自身。…...

Vue一款流行的JavaScript前端框架

1.Vue简介 Vue是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;Vue 都可以胜任。 Vue所关注的核心是MVC…...

GPT-SoVITS

文章目录 model archS1 ModelS2 model model arch S1 model: AR model–ssl tokensS2 model: VITS&#xff0c;ssl 已经是mel 长度线性相关&#xff0c;MRTE(ssl_codes_embs, text, global_mel_emb)模块&#xff0c;将文本加强相关&#xff0c;学到一个参考结果 S1 Model cla…...

linux高级编程——文件IO(常用函数大全)

1.相关介绍及常用函数 Linux高级编程中的目录IO操作是文件系统编程的一个重要组成部分&#xff0c;主要涉及到目录的打开、读取、遍历和关闭等操作。以下是一些基本的目录IO操作和相关的系统调用函数 1.1 opendir函数 打开目录&#xff1a;使用opendir函数打开一个目录&#…...

matplotlib画图

Matplotlib 先写一个最简单的&#xff1a; import matplotlib.pyplot as plt plt.plot([1,4],[2,8]) #plot画折线图plt.show() 确定两个点画一条线 import matplotlib.pyplot as plt x[1,23,4,56,7,6] #x轴数据 y[22,44,56,67,43,2] #y轴数据 s[22,43,33,44,43,7] plt.p…...

Jetpack 各种框架简介

Jetpack是Google推出的一套为Android开发提供极大便利的组件、工具和指导集&#xff0c;旨在帮助开发者快速构建高质量的应用&#xff0c;并遵循最佳实践。 Jetpack不仅是一个提高开发效率的工具集&#xff0c;还是Android开发的未来方向。它通过整合各种组件和工具&#xff0…...

海康VisionMaster使用学习笔记5-开机自启动

开机自启动 在实际应用中&#xff0c;用户会希望机台上电开机后&#xff0c;软件能自启动避免现场人员误操作&#xff0c;减少机台重新上电时的操作步骤以提升效率。 设置 打开VM,点击设置,软件设置->开机自启动->勾选开机自启动->确定 默认运行界面 启动时以设定的…...

驾驭数据之序:SQL序列的奥秘与实现

标题&#xff1a;驾驭数据之序&#xff1a;SQL序列的奥秘与实现 摘要 在数据库管理中&#xff0c;保证数据的有序性和唯一性是至关重要的。SQL序列&#xff08;Sequence&#xff09;作为一种强大的数据库对象&#xff0c;为我们提供了一种在不同数据库系统中生成连续数字的手…...

【LeetCode】148. 排序链表

排序链表 题目描述&#xff1a; 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4]示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;…...

阿里云-java调用短信服务,第三方接口的开启(傻瓜式教程)

第一步&#xff1a;在浏览器中&#xff0c;搜索阿里云 第二步&#xff1a;打开aly的主页 第三步&#xff1a;在最上方的导航栏中&#xff0c;找到云市场&#xff0c;注意不要点击&#xff0c;会自动有触发悬浮框出现&#xff0c;在悬浮框中找到 短信 第四步&#xff1a;点击 短…...

以node / link文件表征的道路网络-----基于南京公路公开数据做路径规划(下)------dijkstra算法的一些简单花样

在不改变dijkstra算法本身的情况下&#xff0c;完全可以从数据源的角度出发&#xff0c;解决我们的一些简单需求&#xff1a; 比较初级且粗暴的玩法&#xff0c;可以是强行赋予一些link极端的路段长度。 对于我们坚决不希望车辆行驶的道路、禁行区、或是危险区&#xff0c;就…...

计算机操作员中级理论知识试题

计算机操作员中级理论知识试题 一、单项选择题 在ASCII编码中,无法显示或打印的字符是()。 A.字符$,%,# B.运算符号*,.,/ C.空格 D.ASCII编码值在0-30间的控制符号将十进制数31.625转换成十六进制数是() A.115.10 B.If.a C.37.5 D.If.10在计算机中,同统一指挥和控制计…...

Redis主从同步配置

1&#xff1a; 安装Redis 参考 linux ubuntu安装redis_ubuntu离线安装redis7.2.5-CSDN博客 2:创建目录 到达redis 根目录 cd /usr/redis/# 创建主从工作目录 mkdir -p replication/6379 # master 节点 mkdir -p replication/6378 # 从节点 mkdir -p replication/6377 # 从节点…...

输出重定向

输出重定向是指将程序的输出&#xff08;标准输出、错误输出等&#xff09;重定向到指定的位置&#xff0c;而不是默认的输出设备&#xff08;通常是终端/控制台&#xff09;。在 Unix/Linux 系统中&#xff0c;输出重定向通过使用符号 >、>>、2> 等来实现。 常见…...

ubuntu20.04挂载机械硬盘

环境说明 1.基于清华源地址下载的ubuntu20.04制作的系统盘&#xff0c;然后安装在PC上&#xff08;固态硬盘&#xff09; 2.机械硬盘无法看见 目的 挂载机械硬盘&#xff0c;开机就能自动启动/挂载 参考链接 https://blog.csdn.net/qq_35624642/article/details/137713143…...

Python轻量级 NoSQL 数据库之tinydb使用详解

概要 在现代应用开发中,使用数据库来存储和管理数据是非常常见的需求。对于简单的数据存储需求,关系型数据库可能显得过于复杂。TinyDB 是一个纯 Python 实现的轻量级 NoSQL 数据库,专为嵌入式场景设计,适用于小型项目、原型开发和教学等场景。本文将详细介绍 TinyDB 库,…...

【数据结构】二叉树(二)遍历

上篇已经了解对二叉树有了大概了解&#xff0c;本篇学习二叉树的前序、中序、后序及层序遍历的递归与非递归共7种遍历方法&#xff0c;快收藏吧~ 目录 1、前序遍历 递归方式&#xff1a; 迭代方式&#xff1a; 2、中序遍历 递归方式&#xff1a; 迭代方式&#xff1a; …...

NGINX 常用内置变量

目录 $remote_addr 变量 $args 变量 $is_args 变量 $document_root 变量 $document_uri 变量 $host 变量 $limit_rate 变量 $remote_port 变量 $remote_port --显示客户端端口 $request_method 变量 --返回请求方式 $request_filename 变量 --返回请求实际路径 $request_uri…...

Windows采用VS2019实现Open3D的C++应用

1、参考链接 https://blog.csdn.net/qq_31254435/article/details/137799739 但是&#xff0c;我的方法和上述链接不大一样&#xff0c;我是采用VS2019进行编译的&#xff0c;方便在Windows平台上验证各种算法。 2、创建一个VS2019的C Console工程 #include <iostream>…...

冒泡排序、选择排序、插入排序,三种简单排序算法的区别?

1、冒泡排序 冒泡排序是从下标 1 遍历到 n&#xff0c;每当遇到大于下一个的&#xff0c;就和上一个交换位置&#xff0c;这样最大的就移动到了 n 的位置&#xff0c;然后从头再从 1 遍历到 n-1&#xff0c;把第二大的移动到 n-1 的位置&#xff0c;依此类推&#xff0c;每次从…...

Docker 日志管理

一、ELK -Filebeat Elasticsearch 数据的存储和检索 常用端口&#xff1a; 9100&#xff1a;elasticsearch-head提供web访问 9200&#xff1a;elasticsearch与其他程序连接或发送消息 9300&#xff1a;elasticsearch集群状态 Logstash 有三个组件构成input&#xff0c;fi…...

JavaScript初级——基础知识

一、JS的HelloWord 1、JS的代码需要编写到script标签中 2、JS的执行是根据语句从上到下一次执行的。 二、JS的编写位置 1、可以将js代码编写到标签的onclick属性中&#xff0c;当我们点击按钮时&#xff0c;js代码才会执行。 2、可以将js代码写在超链接的href属性中&#xff0…...

0817(持久层框架:JDBC,MyBatis)

三层架构&#xff08;表现层&#xff0c;业务层&#xff0c;持久层&#xff09; java中框架的概述&#xff08;表现层、业务层、持久层的关系&#xff09;_控制层业务层持久层的关系-CSDN博客 框架&#xff1a;框架一般处在低层应用平台&#xff08;如J2EE&#xff09;和高层…...

在亚马逊云科技上安全、合规地创建AI大模型训练基础设施并开发AI应用服务

项目简介&#xff1a; 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 本次介绍的是如何在亚马逊云科技利用Servi…...

无人机模拟训练室技术详解

无人机模拟训练室作为现代无人机技术培训的重要组成部分&#xff0c;集成了高精度模拟技术、先进的数据处理能力及高度交互的操作界面&#xff0c;为无人机操作员提供了一个安全、高效、接近实战的训练环境。以下是对无人机模拟训练室技术的详细解析&#xff0c;涵盖系统基础概…...