C#多线程
C#中的多线程编程是开发高效并发应用程序的关键技术之一,它允许程序同时执行多个任务,从而提升应用程序的响应速度和性能。为了更好地理解C#中的多线程使用和定义,我们可以从以下几个方面来探讨:线程的基本概念、创建线程的方法、线程的状态管理以及线程同步机制。
线程的基本概念
在C#中,线程(Thread)是操作系统能够进行运算调度的最小单位,是进程中的基本执行单元。一个进程中可以包含若干个线程,在进程入口执行的第一个线程被视为这个进程的主线程。
每个线程都有自己的调用栈(call stack)、寄存器环境(register context)、线程本地存储(thread-local storage),但它们共享同一进程的虚拟地址空间、文件描述符和其他系统资源。
创建线程的方法
使用Thread
类
最直接的方式是通过System.Threading.Thread
类创建一个新的线程,并指定要在线程中执行的工作。可以通过ThreadStart
或ParameterizedThreadStart
委托来定义线程启动时要执行的方法。
Thread thread = new Thread(new ThreadStart(DoWork));
thread.Start();
或者使用带有参数的构造函数:
Thread thread = new Thread(new ParameterizedThreadStart(DoWork));
thread.Start("参数");
此外,还可以使用Lambda表达式来简化代码:
Thread thread = new Thread(() => Console.WriteLine("Hello from thread"));
thread.Start();
使用Task
类
.NET Framework 4.0引入了Task
类,作为更高级别的抽象用于简化多线程编程。与Thread
不同的是,Task
提供了更好的资源管理和错误处理机制,并且支持取消操作和结果返回等功能。
创建并启动一个任务非常简单:
Task task = Task.Run(() => DoWork());
使用Parallel
类
对于需要并行执行循环或LINQ查询的情况,可以使用System.Threading.Tasks.Parallel
类提供的静态方法如Parallel.For
或Parallel.ForEach
,这些方法可以在多个线程上并行地迭代集合中的元素。
使用BackgroundWorker
组件
BackgroundWorker
是一个方便的组件,适合于Windows Forms或WPF应用程序中执行后台操作而不阻塞用户界面。它可以报告进度并且支持取消操作。
线程的状态管理
线程在其生命周期中有不同的状态,包括就绪、运行、等待、暂停等。可以通过Thread
类提供的属性如IsAlive
、ThreadState
等检查线程的状态。例如,Join()
方法可以让当前线程等待另一个线程完成其执行;而Abort()
方法则会尝试终止线程(需要注意的是,Abort()
已经被标记为过时,不推荐使用)。另外,Sleep()
方法可以使线程休眠一段时间。
线程同步机制
当多个线程访问相同的资源时,可能会导致数据竞争条件或其他问题。为了避免这些问题,必须采用适当的同步策略。C#提供了多种同步原语,如lock
关键字、Monitor
类、Mutex
、SemaphoreSlim
等。
通过锁定机制确保每次只有一个线程能访问特定区域的代码,这样就可以防止并发冲突。
多线程优劣式
优势
-
提高程序的并发性和性能:
-
多线程编程允许程序同时执行多个任务,这不仅提高了程序的并发性,而且使得程序能够更高效地利用系统资源。对于需要处理大量计算、网络操作或I/O密集型任务的应用来说,使用多线程可以避免阻塞主线程,从而提高应用程序的整体响应速度。
-
-
改善用户体验:
-
在图形用户界面(GUI)应用中,保持UI线程的响应性是非常重要的。通过将耗时的操作放在后台线程中执行,用户可以继续与应用程序进行交互,不会因为长时间等待而感到不便。这种非阻塞的方式极大地提升了用户的体验。
-
-
充分利用多核处理器:
-
现代计算机通常配备有多核CPU,多线程编程可以使应用程序有效地利用这些核心,进而提升程序的执行效率。每个线程可以在不同的CPU核心上运行,确保硬件资源得到最大程度的利用。
-
-
代码复用和解耦:
-
将复杂的任务分解为多个独立的线程有助于创建更加模块化和易于维护的代码结构。不同线程负责不同的职责,减少了各个部分之间的依赖关系,促进了代码的重用。
-
-
实现异步操作:
-
异步编程模型是现代软件开发不可或缺的一部分,它允许开发者编写出更加灵活且高效的代码。
-
async/await
关键字简化了异步编程的过程,使编写异步方法变得直观简单。
劣势
-
增加编程复杂度:
-
尽管多线程编程带来了诸多好处,但它也增加了编程的复杂性。开发者需要考虑线程同步、资源共享以及死锁等问题,这些都是单线程环境中不存在的问题。
-
-
容易出现竞态条件:
-
当多个线程尝试访问并修改同一份共享资源时,如果没有正确的同步措施,可能会导致数据竞争,进而产生不可预测的行为或错误的结果。
-
-
资源消耗较大:
-
每个线程都需要占用一定的内存资源,包括栈空间等。如果创建了过多的线程,不仅会浪费系统资源,还可能导致上下文切换频繁,反而降低程序性能。
-
-
调试困难:
-
相比于单线程程序,多线程程序的调试更为复杂。由于多线程环境下的不确定性和并发性,问题重现和定位都变得更加棘手。
-
-
线程池局限性:
-
使用线程池虽然可以减少线程创建销毁的成本,但线程池本身也有其局限性,比如无法直接控制线程的生命周期,也不适合长时间运行的任务。
-
多线程实例
以下五个实例覆盖了C#中常见的多线程编程方式,包括直接创建线程、使用线程池、任务并行库(TPL)、并行化循环以及异步I/O操作。
实例1:使用Thread
类创建并启动线程
using System;
using System.Threading;class Program {static void Main() {Thread thread = new Thread(new ThreadStart(DoWork));thread.Start();Console.WriteLine("主线程继续...");thread.Join(); // 等待子线程结束Console.WriteLine("子线程已完成.");}static void DoWork() {Console.WriteLine("正在工作...");Thread.Sleep(1000); // 模拟耗时操作Console.WriteLine("工作完成.");}
}
在这个例子中,我们创建了一个新的线程来执行DoWork
方法,并在主线程中等待它完成。
实例2:使用线程池执行任务
.NET框架提供了一个内置的线程池,可以通过ThreadPool.QueueUserWorkItem()
方法将工作项排队到线程池中去执行。这种方式非常适合处理短时间的任务,因为它避免了频繁创建销毁线程所带来的开销。
using System;
using System.Threading;class Program {static void Main() {ThreadPool.QueueUserWorkItem(o => DoWork("线程池任务"));Console.WriteLine("主线程继续...");Console.ReadLine();}static void DoWork(string message) {Console.WriteLine($"{message} 正在工作...");Thread.Sleep(1000); // 模拟耗时操作Console.WriteLine($"{message} 工作完成.");}
}
这里展示了如何使用线程池来执行后台任务而不阻塞主线程。
实例3:使用Task
类进行异步操作
从.NET 4.0开始引入的任务并行库(TPL)提供了更高层次的抽象,使得编写并发代码变得更加容易。下面的例子展示了如何使用Task
类来启动异步任务,并且可以在任务完成后获取结果或处理异常。
using System;
using System.Threading.Tasks;class Program {static async Task Main(string[] args) {Task<int> task = Task.Run(() => ComputeSum(1, 100));Console.WriteLine("计算中...");try {int result = await task;Console.WriteLine($"计算结果是: {result}");} catch (Exception ex) {Console.WriteLine(ex.Message);}}static int ComputeSum(int start, int end) {int sum = 0;for (int i = start; i <= end; i++) {sum += i;}return sum;}
}
此示例展示了如何使用Task
来进行异步计算,并使用await
关键字等待结果返回。
实例4:使用Parallel
类并行化循环
对于那些想要并行执行循环或LINQ查询的情况,可以使用System.Threading.Tasks.Parallel
类提供的静态方法如Parallel.For
或Parallel.ForEach
。这些方法可以在多个线程上并行地迭代集合中的元素,从而加速计算密集型任务的执行。
using System;
using System.Threading.Tasks;class Program {static void Main() {Parallel.For(0, 5, i => {Console.WriteLine($"正在处理 {i}");Thread.Sleep(1000); // 模拟耗时操作});}
}
这段代码演示了如何使用Parallel.For
来并行执行循环中的每一项。
实例5:使用async/await
模式简化I/O操作
随着C#语言的发展,async
和await
关键字成为了编写非阻塞代码的标准做法。它们让异步编程变得直观且易于理解,尤其是在I/O密集型应用中表现尤为突出。
using System;
using System.Net.Http;
using System.Threading.Tasks;class Program {static async Task Main(string[] args) {using HttpClient client = new HttpClient();string url = "https://example.com";HttpResponseMessage response = await client.GetAsync(url);string content = await response.Content.ReadAsStringAsync();Console.WriteLine(content);}
}
这个例子展示了如何利用HttpClient
结合async/await
来发起HTTP GET请求,而不会阻塞主线程。
多线程注意事项
1. 线程同步与互斥
当多个线程共享资源或访问同一块内存区域时,必须采取适当的措施来防止竞态条件(Race Condition),即两个或更多的线程同时修改相同的数据导致不一致的结果。C#提供了多种机制来实现线程同步和互斥,如lock
语句、Monitor
类、Mutex
、SemaphoreSlim
等。
2. 后台线程 vs 前台线程
线程可以是前台线程也可以是后台线程,前者会在应用程序结束前一直运行,而后者则不会阻止进程终止。这意味着如果所有前台线程都结束了,那么即使还有后台线程正在运行,整个应用程序也会关闭。因此,在设计应用时要明确区分这两种类型的线程,并根据需求选择合适的类型。
3. 异常处理
由于多线程环境中异常的发生可能更为复杂,因此必须特别注意异常处理策略。每个线程都应该有自己的异常处理逻辑,以防止未捕获的异常导致整个应用程序崩溃。对于TPL中的任务,可以通过ContinueWith
方法附加一个回调函数来处理可能出现的异常,或者直接使用await
操作符配合try-catch
结构。
4. 数据安全与一致性
多线程环境下,数据的一致性和安全性变得尤为重要。如果不加以控制,多个线程可能会并发地读写同一个变量,从而破坏数据的完整性。为此,应当采用线程安全的数据结构,比如.NET提供的并发集合类(如ConcurrentDictionary
、ConcurrentBag
)。
这些集合专为多线程环境设计,可以在不加锁的情况下安全地进行读写操作。
5. 资源管理
创建过多的线程会消耗大量的系统资源,包括CPU时间和内存空间。因此,应合理规划线程的数量,避免不必要的线程创建。利用线程池可以帮助复用现有的线程,减少创建销毁的成本。另外,对于长时间运行的任务,建议考虑使用异步模式(如async/await
),以便更好地管理资源。
6. 避免过度并行化
虽然增加线程数可以在一定程度上提高吞吐量,但并不是越多越好。实际上,过多的线程反而可能导致上下文切换频繁,降低效率。因此,在决定并发度时,应该基于目标硬件平台的特点以及具体的应用场景做出最优选择。
7. 线程启动顺序随机性
值得注意的是,线程之间的启动顺序并非固定不变,而是由操作系统根据当前负载等因素动态决定。这意味着即便你在代码中按顺序启动了多个线程,它们的实际执行顺序可能是随机的。
如果你对某些任务的执行顺序有严格要求,则不应依赖于线程的自然调度,而是通过其他方式(如队列)来保证顺序。
8. 不手动终止线程
尽量不要显式调用Thread.Abort()
来强制终止线程,因为这可能导致资源泄漏或其他不稳定的行为。相反,应该设计好退出机制,让线程能够在完成当前工作后自然结束。例如,可以使用CancellationToken
来通知线程何时应该停止工作。
相关文章:
C#多线程
C#中的多线程编程是开发高效并发应用程序的关键技术之一,它允许程序同时执行多个任务,从而提升应用程序的响应速度和性能。为了更好地理解C#中的多线程使用和定义,我们可以从以下几个方面来探讨:线程的基本概念、创建线程的方法、…...
Apache HTTP 服务器深度性能优化
引言 在前几篇文章中,我们讨论了基础和高级性能优化策略。现在,我们将深入探讨一些具体的优化实践,帮助您实现更精细的控制,并确保Apache服务器在各种复杂环境中都能保持最佳性能。 1. 细粒度的Apache配置调整 1.1 MPM参数微调…...
芯片级IO (Pad) Ring IP Checklist
SoC top顶层数字后端实现都会涉及到IO Ring (PAD Ring)的设计。这里面包括VDD IO,VDDIO IO, Signal IO, Corner IO,Filler IO,IO power cut cell等等。 数字后端零基础入门系列 | Innovus零基础LAB学习Day2 数字IC后端实现TOP F…...
无界wujie网址
文档网址:微前端是什么 | 无界 demo:https://wujie-micro.github.io/demo-main-vue/react17...
vulnhub靶场【DriftingBlues】之6
前言 靶机:DriftingBlues-6,IP地址192.168.1.63,因为重装靶机后期为192.168.1.64 攻击:kali,IP地址192.168.1.16 都采用虚拟机,网卡为桥接模式 主机发现 使用arp-scan -l或netdiscover -r 192.168.1.1…...
心情追忆- Nginx + OpenResty 构建高可用网关
之前,我独自一人开发了一个名为“心情追忆”的小程序,旨在帮助用户记录日常的心情变化及重要时刻。我从项目的构思、设计、前端(小程序)开发、后端搭建到最终部署。经过一个月的努力,通过群聊分享等方式,用…...
太速科技-527-基于3U VPX XCZU15EG+TMS320C6678的信号处理板
基于3U VPX XCZU15EGTMS320C6678的信号处理板 一、板卡概述 本板卡系我司自主研发的基于3U VPX风冷、导冷架构的信号处理板,适用于高速图像处理等。芯片采用工业级设计。 板卡采用标准3U VPX架构,板上集成一片Xilinx公司ZynqUltraScale系列F…...
Vue3源码笔记阅读1——Ref响应式原理
本专栏主要用于记录自己的阅读源码的过程,希望能够加深自己学习印象,也欢迎读者可以帮忙完善。接下来每一篇都会从定义、运用两个层面来进行解析 定义 运用 例子:模板中访问ref(1) <template><div>{{str}}</div> </template> <script> impo…...
多音轨视频使用FFmpeg删除不要音轨方法
近期给孩子找宫崎骏动画,但是有很多是多音轨视频但是默认的都是日语,电视上看没办法所以只能下载后删除音轨文件只保留中文。 方法分两步,先安装FFmpeg在转文件即可。 第一步FFmpeg安装 FFmpeg是一个开源项目,包含了处理视频的…...
AtomGit 开源生态应用开发赛报名开始啦
目录 1、赛项背景2、赛项信息3、报名链接4、赛题一:开发者原创声明(DCO)应用开发赛题要求目标核心功能 5、赛题二:基于 OpenHarmony 的开源社区应用开发简介赛题要求 6、参赛作品提交初赛阶段决赛阶段 7、参赛作品提交方式 1、赛项…...
使用 NVIDIA DALI 计算视频的光流
引言 光流(Optical Flow)是计算机视觉中的一种技术,主要用于估计视频中连续帧之间的运动信息。它通过分析像素在时间维度上的移动来预测运动场,广泛应用于目标跟踪、动作识别、视频稳定等领域。 光流的计算传统上依赖 CPU 或 GP…...
C语言学习day23:WriteProcessMemory函数/游戏内存数据修改工具开发
简言: 上一章我们说了获取应用进程的某数据(data),这一章我们就说说修改内存地址的数据。想要修改内存,那么就需要我们另一个WinAPI函数:WriteProcessMemory()函数。 WriteProcessMemory()函数 函数原型…...
利用 html_table 函数轻松获取网页中的表格数据
背景/引言 在数据爬取的过程中,网页表格数据往往是研究人员和开发者的重要目标之一。无论是统计分析、商业调研还是信息整理,表格数据的结构化特性都使其具有较高的利用价值。然而,如何快速、准确地从网页中提取表格数据始终是爬虫技术的一个…...
Postman接口测试:全局变量/接口关联/加密/解密
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 全局变量和环境变量 全局变量:在postman全局生效的变量,全局唯一 环境变量:在特定环境下生效的变量,本环境内唯一 …...
手机银行模拟器,一款高仿真银行app的模拟器,可以修改姓名 卡号 余额 做转账记录 做流水
📱手机银行模拟器让你自由定制你的金融生活。无论是流水账单、金额,还是个人信息,一切都可以按照你的意愿来模拟修改,让你体验模拟器带来的快乐! 链接:https://pan.quark.cn/s/c2f614f3447f 提取码&#…...
HT7183:16V, 4.5A的DC-DC升压转换器,常用在数码相机里
HT7183描述: HT7183是一款高功率异步升压转换器,集成120mΩ功率开关管,为便携式系统提供高效的小尺寸解决方案。具有2.6V至5.5V输入电压范围,可为各类不同供电的应用提供支持。该器件具备3A开关电流能力,并且能够提供高…...
Cobalt Strike 4.8 用户指南-第十四节 Aggressor 脚本
14.1、什么是Aggressor脚本 Aggressor Script 是Cobalt Strike 3.0版及更高版本中内置的脚本语言。Aggressor 脚本允许你修改和扩展 Cobalt Strike 客户端。 历史 Aggressor Script 是 Armitage 中开源脚本引擎Cortana的精神继承者。Cortana 是通过与 DARPA 的网络快速跟踪计…...
【Qt】QWidget中的常见属性及其功能(二)
目录 六、windowOpacity 例子: 七、cursor 例子: 八、font 九、toolTip 例子: 十、focusPolicy 例子: 十一、styleSheet 计算机中的颜色表示 例子: 六、windowOpacity opacity是不透明度的意思。 用于设…...
对象的克隆 单例模式
1) 如何实现对象的克隆? 1、为什么需要实现对象的克隆? 在某些情况下,需要创建一个与现有对象完全相同的副本,这就是对象克隆。 例如,在需要对对象进行备份、在不同的上下文中使用相同的类型的对象或者实现某些设计…...
预处理内容
预处理是干什么的呢? 分为三点: 1.宏替换 2.头文件导入 3.删除注释 #ifdef #include <iostream> // 定义一个宏,表示当前处于调试模式,在实际调试时可以定义这个宏,发布时取消定义#define DEBUG MODE int ma…...
Docker笔记
1 安装docker b11et3un53m.feishu.cn/wiki/Rfocw7ctXij2RBkShcucLZbrn2d 项目的资料地址(飞书) 当使用docker pull +名字 拉取镜像时报 Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for co…...
条件随机场(CRF)详解:原理、算法与实现(深入浅出)
目录 1. 引言2. 什么是条件随机场?2.1 直观理解2.2 形式化定义 3. CRF的核心要素3.1 特征函数3.2 参数学习 4. 实战案例:命名实体识别5. CRF vs HMM6. CRF的优化与改进6.1 特征选择6.2 正则化 7. 总结与展望参考资料 1. 引言 条件随机场(Conditional Ra…...
C++类与对象学习笔记(一)
https://www.bilibili.com/video/BV1jm4y1w7pa?spm_id_from333.788.player.switch&vd_sourcee8984989cddeb3ef7b7e9fd89098dbe8&p6 🚩🚩🚩来自b站“码农论坛”的视频“类与对象”做的笔记🚩🚩Ὢ…...
wrk如何测试post请求
wrk git地址 https://github.com/wg/wrk wrk 默认是针对 GET 请求的,但它也可以通过添加自定义的 HTTP 请求体和 头部信息来进行 POST 请求的压测。以下是详细的步骤: wrk -t4 -c100 -d30s -s post.lua http://example.com-t4:使用 4 个线…...
rust使用log与env_logger两个crate实现同时向控制台和文件输出日志。并在隔日自动创建新日志文件。
还是老习惯,不用太多的废话。直接上代码。 不过我之说一句话,这块需要自定义一个输出的Target来实现这个功能。 log = { version="0.4.22", default-features = false } env_logger = "0.11.5"pub(crate) fn setup_log_env(log_level: LevelFilter) {...
异步将用户信息存入 Redis 缓存
主要是为了解决Redis的缓存问题,异步将用户信息存入Redis缓存 首先我们需要引入一部线性池 核心概念 异步执行: 异步执行是指任务提交后不会立即等待其完成,而是立即返回并继续执行其他任务。任务将在后台执行,执行结果可以通过…...
WebRTC服务质量(05)- 重传机制(02) NACK判断丢包
WebRTC服务质量(01)- Qos概述 WebRTC服务质量(02)- RTP协议 WebRTC服务质量(03)- RTCP协议 WebRTC服务质量(04)- 重传机制(01) RTX NACK概述 WebRTC服务质量(…...
MySQL 存储过程与函数:增强数据库功能
一、MySQL 存储过程与函数概述 (一)存储过程的定义与特点 存储过程是一组预编译的 SQL 语句集合,它们被存储在数据库中,可根据需要被重复调用。例如,在一个电商系统中,经常需要查询某个时间段内的订单数据…...
丹摩|丹摩助力selenium实现大麦网抢票
丹摩|丹摩助力selenium实现大麦网抢票 声明:非广告,为用户体验 1.引言 在人工智能飞速发展的今天,丹摩智算平台(DAMODEL)以其卓越的AI算力服务脱颖而出,为开发者提供了一个简化AI开发流程的强…...
springcloud-gateway获取应用响应信息乱码
客户端通过springcloud gateway跳转访问tongweb上的应用,接口响应信息乱码。使用postman直接访问tongweb上的应用,响应信息显示正常。 用户gateway中自定义了实现GlobalFilter的Filter类,在该类中获取了上游应用接口的响应信息,直…...
Scala项目(一)
1,创建dao,models,service,ui等软件包 2,在各软件包下创建scala类 软件包dao里的代码 package org.app package daoimport models.BookModelimport scala.collection.mutable.ListBuffer//图书,数据操作…...
node(2) - npm run 原理
1. npm run 执行原理 npm run 命令的原理是执行 package.json 文件中定义的脚本。当你在命令行中运行 npm run 时,npm 会查找 package.json 文件中的 scripts 字段,然后执行对应的脚本命令。 2. 示例 2.1 以 dev:weapp 为例 运行 npm run dev:weapp 命令;npm 会查找 packa…...
概率论得学习和整理24:EXCEL的各种图形,统计图形
目录 0 EXCEL的各种图形,统计图形 1 统计图形 / 直方图 / 其实叫 频度图 hist最合适(用原始数据直接作图) 1.1 什么是频度图 1.2 如何创建频度图,一般是只选中1列数据(1个数组) 1.3 如何修改频度图的宽度 1.4 hist图的一个特…...
【zlm】 webrtc源码讲解三(总结)
目录 setsdp onwrite 编辑 play 参考 setsdp onwrite play 参考 【zlm】 webrtc源码讲解_zlm webrtc-CSDN博客 【zlm】 webrtc源码讲解(二)_webrtc 源码-CSDN博客...
YashanDB共享集群产品能力观测:细节足见功底
本文基于前泽塔数科研发总监-王若楠2024年11月在“2024年国产数据库创新生态大会”-“根”技术专场的演讲整理形成,主要对崖山共享集群YAC的架构、功能、高可用性、性能四大方面进行全面测试,并分享了测试环境和测试结论。 年初,基于某些商业…...
游戏引擎学习第50天
仓库: https://gitee.com/mrxiao_com/2d_game Minkowski 这个算法有点懵逼 回顾 基本上,现在我们所处的阶段是,回顾最初的代码,我们正在讨论我们希望在引擎中实现的所有功能。我们正在做的版本是初步的、粗略的版本,涵盖我们认…...
前端部署实战:从人工发布到全自动化流程
"又发错环境了!"周四下午,测试同学小李急匆匆地找到我。原来是开发人员手动部署时,不小心把测试代码发布到了生产环境。这已经是本月第二次类似的事故了。 回想起每次发布时的场景:手动打包、手动上传、手动替换文件...每一步都战战兢兢,生怕…...
JVM系列之内存区域
每日禅语 有一位年轻和尚,一心求道,多年苦修参禅,但一直没有开悟。有一天,他打听到深山中有一古寺,住持和尚修炼圆通,是得道高僧。于是,年轻和尚打点行装,跋山涉水,千辛万…...
如何用3个月零基础入门网络安全?_网络安全零基础怎么学习
🤟 基于入门网络安全/黑客打造的:👉黑客&网络安全入门&进阶学习资源包 前 言 写这篇教程的初衷是很多朋友都想了解如何入门/转行网络安全,实现自己的“黑客梦”。文章的宗旨是: 1.指出一些自学的误区 2.提供…...
易语言OCR证件照文字识别
一.引言 文字识别,也称为光学字符识别(Optical Character Recognition, OCR),是一种将不同形式的文档(如扫描的纸质文档、PDF文件或数字相机拍摄的图片)中的文字转换成可编辑和可搜索的数据的技术。随着技…...
【人工智能】基于Python的自然语言处理:深入实现文本相似度计算
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 文本相似度计算是自然语言处理(NLP)中的核心任务,广泛应用于搜索引擎、推荐系统、问答系统等领域。本文全面解析文本相似度计算的核心技术,使用Python中的spaCy和sentence-transformers库实现多种方法,包括基…...
基于wifi的火焰报警系统设计(论文+源码)
1 总体方案设计 在本次基于wifi模板的火焰报警系统中,整个系统架构如图2.1所示,其采用STM32F103单片机作为控制器,并结合DS18B20温度传感器,火焰传感器,ESP8266 WiFi通信模块,蜂鸣器,OLED液晶构成整个系统,…...
【第三节】Git 基本操作指南
目录 前言 一、获取与创建项目 1.1 git init 1.2 git clone 二、基本快照操作 2.1 git add 2.2 git status 2.3 git diff 2.4 git commit 2.5 git reset HEAD 三、 文件管理 3.1 git rm 3.2 git mv 四、Git 文件状态 5.1 工作目录 5.2 暂存区 5.3 本地仓库 5…...
GaLore和Q-GaLore:一种记忆高效的预训练和微调策略,用于大型语言模型(LLMs)
GaLore和Q-GaLore:一种记忆高效的预训练和微调策略,用于大型语言模型(LLMs) GaLore和Q-GaLore的设计背景、工作原理及其优势 设计背景 随着大型语言模型(LLMs)的发展,模型的规模和复杂性不断…...
免费开源了一个图床工具 github-spring-boot-starter
文章目录 第一步,新建一个SpringBoot项目第二步,在pom文件里面引入jar包第三步,配置你的github信息github.authorization1、进入github官网,登录账号,点击头像,选择setting2、选择[Developer Settings](htt…...
Android显示系统(13)- 向SurfaceFlinger提交Buffer
Android显示系统(01)- 架构分析 Android显示系统(02)- OpenGL ES - 概述 Android显示系统(03)- OpenGL ES - GLSurfaceView的使用 Android显示系统(04)- OpenGL ES - Shader绘制三角…...
python小课堂(一)
基础语法 1 常量和表达式2 变量和类型2.1 变量是什么2.2 变量语法 3 变量的类型3.1 动态类型特性 4 注释4.1注释是什么 5 输入输出5.1 print的介绍5.2 input 6 运算符6.1 算术运算符在这里插入图片描述6.2 关系运算符6.3 逻辑运算符6.4赋值运算符 1 常量和表达式 在print()中可…...
【原创教程】西门子1500TCP_UDP通信说明大全(下篇)
2.3.3 TRCV故障说明 通讯无法正常连接时,ERROR引脚和STATUS引脚得状态有助于我们判断错误得原因,根据下表得提示,快速排除问题。 2.3.4 TRCV使用 点击TRCV指令得右上角蓝色图标,打开开始组态画面,按照控制要求填写 EN_R:用于激活接收的控制参数,及何时使用TRCV的接收功…...
【报错记录】Ubuntu22.04解决开机卡在 /dev/sda5 : clean , *files , *blocks
一个愿意伫立在巨人肩膀上的农民...... 一、错误现象 本人的电脑安装Windows10和Ubuntu22.04双系统,一次训练中电脑死机无法开机,重启之后便出现如下错误,在网上寻找过很多方法均无效,在root下禁用了samba服务,也无济…...
JumpServer开源堡垒机搭建及使用
目录 一,产品介绍 二,功能介绍 三,系统架构 3.1 应用架构 3.2 组件说明 3.3 逻辑架构 3.3 逻辑架构 四,linux单机部署及方式选择 4.1 操作系统要求(JumpServer-v3系列版本) 4.1.1 数据库 4.1.3创建数据库参考 4.2 在线安装 4.2.1 环境访问 4.3 基于docker容…...