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

深入理解C++中的锁

目录

1.基本互斥锁(std::mutex)

2.递归互斥锁(std::recursive_mutex)

3.带超时机制的互斥锁(std::timed_mutex)

4.带超时机制的递归互斥锁(std::recursive_timed_mutex)

5.共享互斥锁也叫读写锁(std::shared_mutex)

6.带超时机制的共享互斥锁(std::shared_timed_mutex)

7.自旋锁

8.总结


1.基本互斥锁(std::mutex)

含义: std::mutex是最基本的互斥锁,主要用于保护临界区,确保同一时间只有一个线程可以访问共享资源。

使用场景: 当需要保护共享资源不被多个线程同时修改时使用。

特点:简单易用,适用于大多数场景;不能递归锁定,同一线程多次尝试锁定会导致死锁。

以下是一个简单的示例,展示了如何使用 std::mutex 来保护共享数据:

#include <iostream>  
#include <thread>  
#include <mutex>  std::mutex mtx;     //全局互斥锁
int shared_data = 0;   //共享数据void increment_shared_data(int n) {  for (int i = 0; i < n; ++i) {  std::lock_guard<std::mutex> lock(mtx);  ++shared_data;  }  
}  int main() {  std::thread t1(increment_shared_data, 1000);  std::thread t2(increment_shared_data, 1000);  t1.join();  t2.join();  std::cout << "Shared data: " << shared_data << std::endl;  return 0;  
}

 这个程序创建了2个线程,每个线程尝试对counter增加10000次。通过使用std::mutex, 我们确保每次只有一个线程可以增加计数器,避免了数据竞争。

2.递归互斥锁(std::recursive_mutex)

含义std::recursive_mutex允许同一线程多次获取锁而不会发生死锁,这对于递归函数或需要多次锁定的场景非常有用。

使用场景: 在递归函数中需要多次获取同一个锁的情况。

特点:适用于递归调用和需要多次锁定的场景;需要注意避免滥用,因为递归锁的使用会增加锁定次数的复杂性。

示例如下:

#include <iostream>
#include <thread>
#include <mutex>std::recursive_mutex rmtx;void recursive_function(int depth) {rmtx.lock();std::cout << "Depth: " << depth << std::endl;if (depth > 0) {recursive_function(depth - 1);}rmtx.unlock();
}int main() {std::thread t(recursive_function, 5);t.join();return 0;
}

这段代码在递归函数recursive_function中使用std::recursive_mutex。每次调用都会尝试加锁,由于使用的是递归互斥锁,同一线程可以多次成功获取锁。

3.带超时机制的互斥锁(std::timed_mutex)

含义std::timed_mutexstd::mutex的基础上增加了超时功能,允许线程在指定时间内尝试获取锁,如果在超时时间内未成功获取锁,则返回失败。

使用场景: 当你不希望线程因等待锁而无限期阻塞时使用。

特点:适用于需要设置锁获取超时时间的场景;提供try_lock_fortry_lock_until两种超时尝试获取锁的方法。

示例如下:

#include <iostream>  
#include <thread>  
#include <mutex>  
#include <chrono>  std::timed_mutex mtx;  void try_lock_function() {  if (mtx.try_lock_for(std::chrono::seconds(1))) {  std::cout << "Lock acquired!\n";  // 执行受保护的操作  std::this_thread::sleep_for(std::chrono::seconds(2)); // 模拟耗时操作  mtx.unlock(); // 显式解锁  } else {  std::cout << "Failed to acquire lock within timeout.\n";  }  
}  int main() {  std::thread t1(try_lock_function);  std::thread t2(try_lock_function);  t1.join();  t2.join();  return 0;  
}

在这个例子中,两个线程都尝试在 1 秒内获取锁。由于互斥锁在同一时刻只能被一个线程持有,因此至少有一个线程将无法在超时时间内获取锁,并输出相应的消息。

4.带超时机制的递归互斥锁(std::recursive_timed_mutex)

含义std::recursive_timed_mutex结合了std::recursive_mutexstd::timed_mutex的特性,支持递归锁定和超时机制。

使用场景: 适用于需要递归锁定资源,并且希望能够设置尝试获取锁的超时时间的场景。这在需要防止线程在等待锁时无限阻塞的复杂递归调用中特别有用。

特点:适用于递归调用和需要超时机制的场景;提供超时尝试获取递归锁的方法。

示例如下:

#include <iostream>  
#include <thread>  
#include <mutex>  
#include <chrono>  std::recursive_timed_mutex mtx;  void recursive_lock_function() {  if (mtx.try_lock_for(std::chrono::seconds(1))) {  std::cout << "Lock acquired!\n";  // 递归锁定  if (mtx.try_lock_for(std::chrono::seconds(1))) {  std::cout << "Recursive lock acquired!\n";  mtx.unlock(); // 释放递归锁  } else {  std::cout << "Failed to acquire recursive lock within timeout.\n";  }  // ... 执行受保护的操作  mtx.unlock(); // 释放原始锁  } else {  std::cout << "Failed to acquire lock within timeout.\n";  }  
}  int main() {  std::thread t1(recursive_lock_function);  std::thread t2(recursive_lock_function);  t1.join();  t2.join();  return 0;  
}

请注意,由于 std::recursive_timed_mutex 允许递归锁定,上面的示例中展示了如何在已经持有锁的情况下再次尝试获取锁(尽管在这个特定示例中,第二次尝试获取锁是多余的,因为我们已经持有锁了)。然而,在实际情况中,递归锁定可能用于更复杂的场景,其中函数可能会递归调用自己,并且每个递归调用都需要访问受保护的数据。

5.共享互斥锁也叫读写锁(std::shared_mutex)

含义std::shared_mutex允许多个线程同时读取,但只有一个线程可以写入。这在读多写少的场景下非常有用。

使用场景: 适用于读操作远多于写操作的情况。

特点:适用于读多写少的场景;读操作和写操作使用不同的锁定机制。

示例如下:


#include <iostream>
#include <thread>
#include <shared_mutex>std::shared_mutex shmtx;void read_shared(int id) {std::shared_lock<std::shared_mutex> lock(shmtx); // 共享锁std::cout << "Thread " << id << " is reading" << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(100));
}void write_shared(int id) {std::unique_lock<std::shared_mutex> lock(shmtx); // 独占锁std::cout << "Thread " << id << " is writing" << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(100));
}int main() {std::thread readers[5], writer(write_shared, 1);for (int i = 0; i < 5; ++i) {readers[i] = std::thread(read_shared, i + 2);}writer.join();for (auto& reader : readers) {reader.join();}return 0;
}

输出结果可能会有所不同,因为读写顺序由操作系统的线程调度决定。本例中,一个写线程在修改数据,多个读线程在同时读数据。通过std::shared_mutex,我们允许多个读操作同时进行,但写操作是独占的。

6.带超时机制的共享互斥锁(std::shared_timed_mutex)

含义std::shared_timed_mutex 是 C++ 标准库中的一个同步原语,它结合了 std::shared_mutex(共享互斥锁)和超时机制的特性。std::shared_mutex 允许多个线程同时以共享模式持有锁(即读取操作可以并发执行),但每次只有一个线程能以独占模式持有锁(即写入操作是互斥的)。通过添加超时机制,std::shared_timed_mutex 允许线程尝试以共享模式或独占模式获取锁,并设置一个超时时间,如果在这段时间内未能成功获取锁,则可以放弃并继续执行其他操作。

使用场景:当你不希望线程因等待锁而无限期阻塞时使用。

特点:适用于读多写少且需要超时机制的场景;提供超时尝试获取共享锁的方法。

示例如下:

#include <iostream>
#include <thread>
#include <shared_mutex>
#include <chrono>std::shared_timed_mutex shtmmtx;void try_read_shared(int id) {if (shtmmtx.try_lock_shared_for(std::chrono::milliseconds(100))) {std::cout << "Thread " << id << " is reading" << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(50));shtmmtx.unlock_shared();} else {std::cout << "Thread " << id << " could not read" << std::endl;}
}void try_write_shared(int id) {if (shtmmtx.try_lock_for(std::chrono::milliseconds(100))) {std::cout << "Thread " << id << " is writing" << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(50));shtmmtx.unlock();} else {std::cout << "Thread " << id << " could not write" << std::endl;}
}int main() {std::thread readers[5], writer(try_write_shared, 1);for (int i = 0; i < 5; ++i) {readers[i] = std::thread(try_read_shared, i + 2);}writer.join();for (auto& reader : readers) {reader.join();}return 0;
}

7.自旋锁

含义:在C++中,自旋锁(spinlock)是一种低级的同步机制,用于保护共享资源,防止多个线程同时访问。与互斥锁(mutex)不同,当自旋锁被锁定时,尝试获取锁的线程会不断循环检查锁是否可用,而不是进入睡眠状态等待锁被释放。这意味着,自旋锁在等待时间很短的情况下是非常有效的,但如果等待时间过长,会导致CPU资源的浪费。

C++标准库本身并不直接提供自旋锁的实现,但你可以使用<atomic>库中的原子操作来手动实现一个自旋锁,或者使用特定平台提供的API(如Windows的SRWLOCK或POSIX的pthread_spinlock_t)。

使用场景:自旋锁适用于锁持有时间非常短且线程不希望在操作系统调度中频繁上下文切换的场景。这通常用在低延迟系统中,或者当线程数量不多于CPU核心数量时,确保CPU不会在等待锁时空闲。

示例如下:

#include <atomic>  
#include <iostream>  
#include <thread>  
#include <chrono>  class Spinlock {  
private:  std::atomic_flag lock_ = ATOMIC_FLAG_INIT;  public:  void lock() {  while (lock_.test_and_set(std::memory_order_acquire)) {  // 循环直到锁被释放  }  }  void unlock() {  lock_.clear(std::memory_order_release);  }  bool try_lock() {  return !lock_.test_and_set(std::memory_order_acquire);  }  
};  void threadFunction(Spinlock& lock, int id) {  lock.lock();  std::cout << "Thread " << id << " entered critical section\n";  std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟耗时操作  std::cout << "Thread " << id << " leaving critical section\n";  lock.unlock();  
}  int main() {  Spinlock lock;  std::thread t1(threadFunction, std::ref(lock), 1);  std::thread t2(threadFunction, std::ref(lock), 2);  t1.join();  t2.join();  return 0;  
}

        在这个例子中,Spinlock 类使用了一个 std::atomic_flag 类型的成员变量 lock_ 来实现锁的功能。lock_ 的 test_and_set 方法会尝试将标志设置为 true 并返回之前的值。如果返回 false,表示锁之前未被锁定,当前线程成功获取锁;如果返回 true,表示锁已被其他线程持有,当前线程需要继续循环等待。

        请注意,自旋锁在多核处理器上且等待时间较短时通常表现良好,但在等待时间较长或锁竞争激烈时可能会导致性能问题。因此,在选择使用自旋锁时,需要根据具体的应用场景和性能要求做出合理的选择。

8.总结

        C++标准库提供了多种类型的互斥锁,每种锁都有其特定的用途和特点。选择合适的互斥锁类型可以有效提高程序的并发性能和安全性。

C++惯用法之RAII思想: 资源管理_raii 思想-CSDN博客

相关文章:

深入理解C++中的锁

目录 1.基本互斥锁&#xff08;std::mutex&#xff09; 2.递归互斥锁&#xff08;std::recursive_mutex&#xff09; 3.带超时机制的互斥锁&#xff08;std::timed_mutex&#xff09; 4.带超时机制的递归互斥锁&#xff08;std::recursive_timed_mutex&#xff09; 5.共享…...

压缩pdf文件大小,压缩pdf文件大小软件哪个好

在数字化时代&#xff0c;PDF文件因其卓越的跨平台兼容性和稳定性而成为工作与学习的好帮手。然而&#xff0c;当PDF文件体积过大时&#xff0c;传输和存储便成了一项挑战。别担心&#xff0c;本文将为你揭秘如何快速压缩PDF文件&#xff0c;让你的文档轻装上路&#xff01; 压…...

难道 Java 已经过时了?

当一门技术已经存在许多年了&#xff0c;它可能会失去竞争力&#xff0c;而后黯然退场&#xff0c;默默地离开&#xff0c;这对大部分的人来说就已经算是过时了。 Java 于 1995 年正式上线&#xff0c;至今已经走过了 27 个年头&#xff0c;在众多编程技术里算是年龄比较大的语…...

华为OD机考题(​HJ32 密码截取)

前言 经过前期的数据结构和算法学习&#xff0c;开始以OD机考题作为练习题&#xff0c;继续加强下熟练程度。有需要的可以同步练习下。 描述 Catcher是MCA国的情报员&#xff0c;他工作时发现敌国会用一些对称的密码进行通信&#xff0c;比如像这些ABBA&#xff0c;ABA&…...

【高考志愿】测绘科学与技术

目录 一、专业介绍 1.1 专业概述 1.2 专业方向 1.3 课程内容 二、就业前景 三、报考注意事项 四、测绘科学与技术专业排名 五、职业规划与未来发展 高考志愿选择测绘科学与技术专业&#xff0c;对于许多有志于空间信息技术领域发展的学生来说&#xff0c;无疑是一个极具…...

SpringBoot异步接口实现 提升吞吐量

前言 Servlet 3.0之前&#xff1a;HTTP请求由单一线程处理。Servlet 3.0之后&#xff1a;支持异步处理&#xff0c;提高系统吞吐量。 SpringBoot 异步接口实现方式 AsyncContext&#xff1a;Servlet层级&#xff0c;不常用。Callable&#xff1a;使用java.util.concurrent.C…...

C语言快速学习笔记

学习网站&#xff1a;C 语言教程 | 菜鸟教程 (runoob.com)C 语言教程 | 菜鸟教程 (runoob.com)C 语言教程 | 菜鸟教程 (runoob.com) 这个网站知识完整&#xff0c;讲解清晰。 在线C语言编程工具&#xff1a;菜鸟教程在线编辑器 (runoob.com) 国外学习网站&#xff1a;C语言介…...

如何选择易用性高的项目管理软件?

随着项目管理在各行各业的广泛应用&#xff0c;选择一款易用性高的项目管理软件变得越来越重要。易用性高的软件可以帮助企业提高工作效率&#xff0c;降低管理成本&#xff0c;同时还能提升团队之间的协作能力。那么&#xff0c;如何选择一款易用性高的项目管理软件呢&#xf…...

vue3基于uni-app 封装小程序request请求

const BASE_URL https://47.122.26.142; // 替换为你的 API 基础 URL const token uni.getStorageSync(token);const request (url: string, method: any, data {}, headers {}) > {return new Promise((resolve, reject) > {uni.request({url: ${BASE_URL}${url},m…...

YOLO在目标检测与视频轨迹追踪中的应用

YOLO在目标检测与视频轨迹追踪中的应用 引言 在计算机视觉领域&#xff0c;目标检测与视频轨迹追踪是两个至关重要的研究方向。随着深度学习技术的飞速发展&#xff0c;尤其是卷积神经网络&#xff08;CNN&#xff09;的广泛应用&#xff0c;目标检测与视频轨迹追踪的性能得到…...

版本控制系统:Git 纯应用(持续更新)

基本操作 ctrl上行键&#xff1a;上次代码 本地仓库&#xff1a;Git init 新建文件&#xff1a;touch xxxx.xxx 查看状态&#xff1a;Git status 文件从工作区——暂存区&#xff1a;Git add ./文件名(.是通配符代表所有) 暂存区——仓库&#xff1a;Git commit -m &…...

从0开始搭建vue项目

#先查下电脑有没有安装过node和npm node -v npm -v #安装vue npm install -g vue #安装webpack npm install webpack -g 都安装好后&#xff0c;进入你想创建的文件夹内 创建名字&#xff1a;vue init webpack <project_name> 就默认回车 然后根据项目需求Y/n 比如…...

Java框架常见面试题

在Java框架面试中&#xff0c;面试官通常会考察候选人对常见Java框架的理解、使用经验以及解决问题的能力。以下是一些常见的Java框架面试题及其详细回答&#xff1a; 1. Spring框架相关问题 问题&#xff1a;Spring框架的核心组件有哪些&#xff1f;它们各自的作用是什么&am…...

linux c 应用编程定时器函数

在 Linux C 应用编程中&#xff0c;对于多线程编程中的定时器函数使用&#xff0c;通常可以借助 pthread 库和系统提供的定时器相关的函数来实现。 首先&#xff0c;常见的定时器函数有 setitimer() 和 alarm() 。setitimer() 函数可以更精确地设置定时器&#xff0c;它可以设…...

设备调试上位机GUI

C Fast Qt C 前端 原来真的不需要在 design 上画来画去&#xff0c;有chat-gpt 那里不知道问哪里 全是组件拼起来的,不需要画,最后发现其实也是定式模式,跟着AI 学套路 最终前端界面 鼠标邮件绑定几个功能 太nice 了 在再加一个全局的日志模块 yyds MVC 的架构&#xff0c; 视图…...

项目管理系统厂商:奥博思发布《项目管理系统助力 IPD 高效落地》演讲

一场题为&#xff1a;“标准为基&#xff0c;项目之上 &#xff0c;持续提升 PMO 卓越中心”的全国 PMO 专业人士年度盛会在京召开。会议围绕 PMO 卓越中心能力提升、项目管理标准化、项目管理体系建设等核心话题力邀业界专家、卓有建树的 PMO 实践精英来演讲、交流、分享。 奥…...

Java项目总结1

1.什么是面向对象&#xff08;此对象非彼对象&#xff09; “面向对象的方法主要是把事物给对象化&#xff0c;包括其属性和行为。面向对象编程更贴近实际生活的思想。总体来说面向对象的底层还是面向过程&#xff0c;面向过程抽象成类&#xff0c;然后封装&#xff0c;方便使用…...

Java中的类加载机制详解

Java中的类加载机制详解 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 类加载机制概述 在Java中&#xff0c;类加载机制是Java虚拟机&#xff08;JVM&#xff09;将.class文件加载到内存中并转换…...

SwiftUI 中 Grid 内多个 NavigationLink 同时发生导航之诡异问题的解决

问题现象 不知小伙伴们发现了没有?在 SwiftUI 中如果有多个 NavigationLink 视图嵌入在 Grid(包括 LazyVGrid 和 LazyHGrid)容器中,点击其中任意一个 NavigationLink 都会导致所有导航一起发生。 如上图所示,点击 Grid 中任何一个 NavigationLink,所有 NavigationLink 都…...

51单片机第21步_将TIM0用作两个8位定时器同时将TIM1用作波特率发生器

本章重点讲解将TIM0用作两个8位定时器&#xff0c;同时将TIM1用作波特率发生器。 当定时器T0在方式3时&#xff0c;T1不能产生中断&#xff0c;但可以正常工作在方式0、1、2下&#xff0c;大多数情况下&#xff0c;T1将用作串口的波特率发生器。 1、定时器0工作在模式3框图&a…...

API-元素尺寸与位置

学习目标&#xff1a; 掌握元素尺寸与位置 学习内容&#xff1a; 元素尺寸与位置仿京东固定导航栏案例实现bilibili点击小滑块移动效果 元素尺寸与位置&#xff1a; 使用场景&#xff1a; 前面案例滚动多少距离&#xff0c;都是我们自己算的&#xff0c;最好是页面滚动到某个…...

C语言中的基础指针操作

在C语言中&#xff0c;指针是一个非常重要的概念&#xff0c;它提供了直接访问内存地址的能力。指针变量用于存储内存地址&#xff0c;而不是数据值&#xff0c;在某种意义上和门牌号具有相似含义&#xff1a;指针是一个变量&#xff0c;其存储的是另一个变量的内存地址&#x…...

LabVIEW环境下OCR文字识别的实现策略与挑战解析

引言 在自动化测试领域&#xff0c;OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;技术扮演着重要角色&#xff0c;它能够将图像中的文字转换成机器可编辑的格式。对于使用LabVIEW约5个月&#xff0c;主要进行仪器控制与数据采集的你而言…...

中英双语介绍美国的州:堪萨斯州(Kansas)

中文版 堪萨斯州简介 堪萨斯州&#xff08;Kansas&#xff09;位于美国中部&#xff0c;以其广阔的平原、丰富的农业资源和多样的文化遗产而著称。以下是对堪萨斯州的详细介绍&#xff0c;包括其地理位置、人口、经济、教育、文化和主要城市。 地理位置 堪萨斯州位于美国中…...

信息收集---端口服务信息收集

1. 什么是端口 是设备与外界通讯交流的出口。端口可分为虚拟端口和物理端口&#xff0c;其中虚拟端口指计算机内部或交换机路由器内的端口&#xff0c;不可见。例如计算机中的80端口、21端口、23端口等。物理端口又称为接口&#xff0c;是可见端口&#xff0c;计算机背板的RJ45…...

Python知识点背诵手册,超详细知识梳理

一、手册介绍 《Python知识点背诵手册》是一份详尽的Python学习资料&#xff0c;旨在帮助学习者系统地掌握Python语言的基础知识和进阶技能。该手册将Python的所有关键语法和概念进行了精炼的总结&#xff0c;并以易于理解和记忆的方式呈现。以下是手册的主要特点和内容概述&a…...

【Pytorch实用教程】如何在多个GPU上使用分布式数据并行进行训练模型

文章目录 1. 代码(可直接运行,含随机生成的训练数据)2. 代码的详细解释2.1. 导入必要的库和模块2.2. 设置每个进程的初始设置2.3. 随机生成数据集类 `RandomDataset`2.4. 训练函数 `train`1. 代码(可直接运行,含随机生成的训练数据) 以下是一个基于PyTorch的多GPU分布式…...

PIL,OpenCV,Pytorch处理图像时的通道顺序(颜色,长宽深)

项目颜色通道顺序长宽通道顺序数据类型取值范围PILRGBHWCndarray0-255 (byte)OpenCVBGRHWCndarray0-255 (byte)PyTorchRGB/BGR (取决于如何读取)(N)CHWtensor0-1 (float, 标准化后); 0-255 (int, 未标准化) 注意以下几点&#xff1a; 颜色通道顺序&#xff1a;PIL默认使用RGB顺…...

经纬恒润亮相2024世界智能产业博览会

近日&#xff0c;以“智行天下 能动未来”为主题的2024世界智能产业博览会&#xff08;以下简称“智博会”&#xff09;在国家会展中心&#xff08;天津&#xff09;成功举办。本次智博会上&#xff0c;经纬恒润自主研发的汽车电子产品联合天津&#xff08;西青&#xff09;国家…...

Python序列化和反序列化

一.序列化和反序列化 在Python中&#xff0c;序列化&#xff08;Serialization&#xff09;和反序列化&#xff08;Deserialization&#xff09;是处理对象数据的过程&#xff0c;主要用于对象的存储或网络传输。 序列化&#xff08;Serialization&#xff09; 序列化是将Pyth…...

Stream toArray 好过collect

toArray 比collect 更好用&#xff0c;这样就不需要判断Null。 if(_user.getUserRole()!null) {_user.setRole(_roleList.stream().filter(_e->_e.getRoleId()_user.getUserRole()).toArray(Role[]::new)[0]); } if(_user.getUserRole()!null) {_user.setRole(_roleList.s…...

qt/c++/mysql教务管理系统

简介 qt/c/mysql教务管理系统 学生端&#xff0c;教师端&#xff0c;管理员端 演示 qt/c/mysql教务管理系统 源码获取 printf("白嫖勿扰,需要的加v%s","ywj17347418171");...

Echarts公共方法

Vue引入Echarts install 1.安装Echartsnpm install echarts --save 2.项目全局引入形式--#main.js 全局引入形式import * as echarts from "echarts"Vue.prototype.$echarts echarts 公共方法JS /*** author: wangjie* description: 通用echarts图表封装* date: …...

鸿蒙学习(二)

文章目录 1、弹窗2、走马灯&#xff08;实现轮播图效果&#xff09;3、注解6、多选框、单选框7、Stack8、TextTimer9、DatePicker 1、弹窗 显示提示信息或者用于用户交互 导入模块 prompt 接口 showToast:显示toast showDialog:显示对话框 showContextMenu:显示上下文菜单 sh…...

企业机构营销目前106短信群发还有用吗?此文告诉你该如何抉择!

在当今竞争激烈的企业营销环境中&#xff0c;106短信群发平台依然是众多企业机构青睐的营销工具之一。尽管互联网技术的发展带来了多样化的沟通方式&#xff0c;但106短信群发凭借其直达性强、成本低廉、覆盖广泛等优势&#xff0c;仍然保持着不错的营销效果。然而&#xff0c;…...

DJYGUI AI低代码图形编程开发平台:开启嵌入式软件图形编程新纪元

在科技高速发展的当今时代&#xff0c;软件开发行业对创新和高效的需求日益增长。DJYGUI AI低代码图形编程开发平台的出现&#xff0c;为智能屏、物联屏、串口屏等嵌入式显示设备领域带来了全新的机遇。该平台由都江堰操作系统 AI 代码自动生成平台研发&#xff0c;具有显著的优…...

为什么不能在foreach中删除元素

文章目录 快速失败机制&#xff08;fail-fast&#xff09;for-each删除元素为什么报错原因分析逻辑分析 如何正确的删除元素remove 后 breakfor 循环使用 Iterator 总结 快速失败机制&#xff08;fail-fast&#xff09; In systems design, a fail-fast system is one which i…...

python学习-tuple及str

为什么需要元组 定义元组 元组的相关操作 元组的相关操作 - 注意事项 元组的特点 字符串 字符串的下标&#xff08;索引&#xff09; 同元组一样&#xff0c;字符串是一个&#xff1a;无法修改的数据容器。 如果必须要修改字符串&#xff0c;只能得到一个新的字符串&#xff…...

Python深度理解系列之【排序算法——冒泡排序】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️木道寻的主页 文章目录 &#x1f525;前言&#x1f680;冒泡排序python实现算法实现图形化算法展示 ⭐️⭐️⭐️总结 &#x1f525;前…...

边界框在目标检测中的作用与应用

目标检测是计算机视觉领域的核心任务之一&#xff0c;旨在从图像或视频中识别和定位感兴趣的目标。边界框&#xff08;Bounding Box&#xff09;是目标检测中常用的一种表示方法&#xff0c;用于确定目标在图像中的确切位置。本文将详细探讨边界框的概念、它在目标检测中的角色…...

linux 环境报错:Peer reports incompatible or unsupported protocol version

出现问题的原因&#xff1a; curl 不兼容或不支持的协议版本。 解决方案&#xff1a; yum update -y nss curl libcurl如此继续之前的操作即可。...

深入解析:Java爬虫的本质是什么?

深入解析&#xff1a;Java爬虫的本质是什么&#xff1f; 引言&#xff1a; 随着互联网的快速发展&#xff0c;获取网络数据已成为许多应用场景中的重要需求。而爬虫作为一种自动化程序&#xff0c;能够模拟人类浏览器的行为&#xff0c;从网页中提取所需信息&#xff0c;成为了…...

【Matlab 六自由度机器人】机器人动力学之推导拉格朗日方程(附MATLAB机器人动力学拉格朗日方程推导代码)

【Matlab 六自由度机器人】机器人动力学概述 近期更新前言正文一、拉格朗日方程的推导1. 单自由度系统2. 单连杆机械臂系统3. 双连杆机械臂系统 二、MATLAB实例推导1. 机器人模型的建立2. 动力学代码 总结参考文献 近期更新 【汇总】 【Matlab 六自由度机器人】系列文章汇总 …...

线下生鲜蔬果店做小程序有什么方法

生鲜蔬果是生活所需&#xff0c;大小商家众多&#xff0c;零售批发各种经营模式&#xff0c;小摊贩或是超市门店都有着目标客户或准属性群体。竞争和获客转化也促进着商家寻找客源和加快线上进程。 尤其是以微信社交为主的私域场景&#xff0c;普客/会员都需要精细化管理营收和…...

几种linux开机自启脚本的方法

几种linux开机自启脚本的方法 1. 脚本添加到init.d目录中2. 创建服务service&#xff08;推荐&#xff09;3. /etc/profile & /etc/profile.d&#xff08;不推荐&#xff09;4. /etc/rc.local 本文以启动jenkins节点为例&#xff0c;需要持久连接&#xff0c;实现开机自启 …...

Qt开发笔记:Qt3D三维开发笔记(一):Qt3D三维开发基础概念介绍

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/140059315 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、O…...

Firewalld 防火墙基础

Firewalld 防火墙基础 一、Firewalld概述firewalld 简介firewalld 和 iptables 的关系firewalld 与 iptables service 的区别 二、Firewalld 网络区域区域介绍Firewalld数据处理流程 三、Firewalld 防火墙的配置方法firewall-config 图形工具“区域”选项卡“服务”选项卡改变防…...

针对 Windows 10 的功能更新,版本 22H2 - 错误 0xc1900204

最近想帮女朋友生win11发现她电脑安装更新总是卡到安装%10这里失败 原来是安装路径被修改过了&#xff0c;改回c盘 win R → 输入regedit 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion...

goframe框架规范限制(but it should be named with “Res“ suffix like “XxxRes“)

背景&#xff1a; 首页公司最近要启动一个项目&#xff0c;公司主要业务是用java开发的&#xff0c;但是目前这个方向的项目&#xff0c;公司要求部署在主机上&#xff0c;就是普通的一台电脑上&#xff0c;电脑配置不详&#xff0c;还有经常开关机&#xff0c;所以用java面临…...

格式化选NTFS还是exFAT 格式化NTFS后Mac不能用怎么办 移动硬盘格式化ntfs和exfat的区别

面对硬盘、U盘或移动硬盘的格式化决策&#xff0c;NTFS与exFAT作为主流的文件系统&#xff0c;用户在选择时可以根据它们的不同特点来选择适用场景。下面我们来看看格式化选NTFS还是exFAT&#xff0c;格式化NTFS后Mac不能用怎么办的相关内容。 一、格式化选NTFS还是exFAT 在数…...

LiveNVR监控流媒体Onvif/RTSP用户手册-视频广场:状态记录、播放、回放入口、筛选在线离线、搜索

LiveNVR监控流媒体Onvif/RTSP用户手册-视频广场:状态记录、播放、回放入口、筛选在线离线、搜索 1、视频广场1.1、搜索筛选1.2、状态记录1.3、播放1.4、视频信息1.5、回放入口 2、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、视频广场 1.1、搜索筛选 可以下拉筛选 在线、离线 &a…...

大气热力学(2)——热力学基础

本篇文章源自我在 2021 年暑假自学大气物理相关知识时手写的笔记&#xff0c;现转化为电子版本以作存档。相较于手写笔记&#xff0c;电子版的部分内容有补充和修改。笔记内容大部分为公式的推导过程。 文章目录 2.0 本文所用符号一览2.1 准静态过程2.2 热量和热容量2.2.1 热量…...

电子元器件基础知识总结

1.0 电阻 电阻的定义&#xff1a;导体对电流的阻碍作用称之为电阻【每一种导体都有内阻的存在】 闭合的电路中电子的移动输出有多快&#xff1f;电子在导体中的移动速度是很慢的 【铜线中电流的移动速度】 电子受到原子核的束缚&#xff0c;移动的速度很慢&#xff0c;在电压足…...

利用YOLOv8识别自定义模型

一、背景介绍 最近项目需要识别自定义物品&#xff0c;于是学习利用YOLOv8算法&#xff0c;实现物品识别。由于物体类别不再常规模型中&#xff0c;因此需要自己训练相应的模型&#xff0c;特此记录模型训练的过程。 二、训练模型的步骤 1.拍照获取训练图片&#xff08;训练图…...

Linux高并发服务器开发(八)Socket和TCP

文章目录 1 IPV4套接字结构体2 TCP客户端函数 3 TCP服务器流程函数代码粘包 4 三次握手5 四次挥手6 滑动窗口 1 IPV4套接字结构体 2 TCP客户端 特点&#xff1a;出错重传 每次发送数据对方都会回ACK&#xff0c;可靠 tcp是打电话的模型&#xff0c;建立连接 使用连接 关闭连接…...

LLM - 神经网络的训练过程

1. 对于回归问题&#xff0c;用损失函数来计算预测值和真实值的差异&#xff0c;一种常用的公式是如下图所示(Mean Square Error)&#xff0c;如果损失函数的值越小说明神经网络学习越准确&#xff0c;所以神经网络训练目标是减小损失函数的值&#xff0c; 2. 对于分类问题&…...

东风奕派eπ008岚图FREE318双星闪耀

6月14日晚,东风汽车在湖北武汉和四川雅安两地同步举行盛大发布会,旗下两款重磅新能源车型——东风奕派的eπ008和东风岚图的FREE 318正式上市。这两款新车的推出,不仅进一步巩固了东风汽车在新能源市场的领先地位,也为消费者带来了更加多元化的选择和无与伦比的驾驶体验。e…...

【本地运行chatgpt-web】启动前端项目和service服务端项目,也是使用nodejs进行开发的。两个都运行成功才可以使用!

1&#xff0c;启动web界面 https://github.com/Chanzhaoyu/chatgpt-web#node https://nodejs.org/en/download/package-manager # 使用nvm 安装最新的 20 版本。 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source /root/.bashrc n…...

AWS安全性身份和合规性之Identity and Access Management(IAM)

通过AWS Identity and Access Management&#xff08;IAM&#xff09;&#xff0c;您可以指定谁或什么能够访问AWS中的服务和资源、集中管理精细权限&#xff0c;并分析访问权限以优化跨AWS的权限。 比如一家软件开发公司需要在AWS上创建多个开发人员账户&#xff0c;并对其进…...

HBase安装

安装HBase 提示&#xff1a;需要安装好hadoop和zookeeper 安装zookeeper可参考 一、确定HBase版本 去网站确认 https://hbase.apache.org/book.html#hadoop二、下载HBase安装包 去清华大学镜像站下载 https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/三、安装HBase …...

探索分布式系统的 38 个核心知识点

分布式系统是现代计算领域的一个重要分支&#xff0c;它通过将任务分布在多个计算机上&#xff0c;实现了高效率、高可用性和可扩展性。了解分布式系统的基本原理和关键概念对于开发者、系统管理员和计算机科学专业的学生来说至关重要。本文将为您介绍分布式系统的 38 个核心知…...

Github 2024-05-27 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-27统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目5TypeScript项目3HTML项目1Go项目1非开发语言项目1Rust项目1Svelte项目1Jupyter Notebook项目1免费编程书籍和学习资源清单 创建周期…...