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

go语言使用互斥锁进行同步

我们可以利用互斥锁来保护代码中的关键部分从而确保每次只能有一个goroutine访问共享资源。这样一来就能避免竞争条件的问题。几乎所有支持并发编程的语言中都使用了类似互斥锁的机制。在本章中我们首先会了解互斥锁的功能。之后还会探讨一种名为“读写互斥锁”的特殊类型的互斥锁。读写互斥锁能在我们只需要在修改共享资源时才阻止并发操作的情况下帮助我们提升性能。利用这种机制我们可以允许多个进程同时读取共享资源而与此同时又能确保只有某个进程能够进行写入操作。我们将通过一个示例来了解读写互斥锁的用法还会学习其内部原理并亲手实现一个类似的互斥锁。使用互斥量保护临界区如果我们能确保每次只有一条执行线程能够访问那些关键代码段那该多好啊。这就是互斥锁的作用所在。可以把互斥锁看作是一种“物理锁”它能防止多个协程同时访问代码中的特定部分。只要每次只有一个协程在访问关键代码段就能避免竞争条件的问题。因为竞争条件只有在那两个或多个协程同时尝试访问同一资源时才会发生。我们可以利用互斥锁来标记代码中临界区的起始和结束位置。当某个协程进入由互斥锁保护的临界区时它首先会通过程序代码中的指令明确地锁定该互斥锁。之后协程开始执行临界区内的代码。当执行完成后它会释放互斥锁这样其他协程就可以进入该临界区了。如果另一个协程试图锁定一个已经被占用的互斥锁那么该协程将被挂起直到互斥锁被释放为止。如果有多个协程都在等待锁的释放那么只会有一个协程能够继续执行而那个协程就是下一个成功获得互斥锁的协程。所谓“互斥锁”其实就是一种用于防止竞争条件的并发控制机制。它确保同一时间只能有一个执行单元比如一个协程或内核级线程进入临界区域。如果有两个执行单元同时试图获取对该互斥锁的访问权那么互斥锁的规则会保证只有一个协程能够成功获取访问权而另一个执行单元则必须等待直到互斥锁再次变为可用状态。在 Go 语言中互斥锁的功能由sync包中的Mutex类提供。通过Mutex类我们可以使用Lock()和Unlock()这两个方法来实现对资源的锁定与解锁操作。packagemainimport(fmtsynctime)funcstingy(money*int,mutex*sync.Mutex){fori:0;i1000000;i{// 进入临界区之前先锁定互斥变量mutex.Lock()*money10// 离开临界区之后解锁互斥变量mutex.Unlock()}fmt.Println(Stingy Done)}funcspendy(money*int,mutex*sync.Mutex){fori:0;i1000000;i{mutex.Lock()*money-10mutex.Unlock()}fmt.Println(Spendy Done)}funcmain(){money:100mutex:sync.Mutex{}gostingy(money,mutex)gospendy(money,mutex)time.Sleep(2*time.Second)mutex.Lock()fmt.Println(Money in bank account: ,money)mutex.Unlock()}在我们的主函数中当各个协程执行完成后我们在读取“money”变量时也会使用互斥锁来确保同步。虽然由于我们设置了等待时间来确保所有协程都已完成执行因此出现竞争条件的概率很低。但即便如此保护共享资源始终是良好的编程习惯。使用互斥锁以及后面章节中介绍的其他同步机制可以确保协程能够读取到该变量的最新值。请注意我们必须保护所有关键代码段包括那些goroutine仅用于读取共享资源的区域。编译器的优化措施可能会重新调整指令的执行顺序从而导致指令以不同的方式被执行。通过使用适当的同步机制比如互斥锁我们可以确保自己能够读取到共享资源的最新版本。互斥锁是如何实现的呢互斥锁的实现通常需要操作系统和硬件的支持。如果系统只有一个处理器那么我们可以通过在某个线程持有锁时禁止中断的方式来实现互斥锁。这样一来其他线程就不会干扰当前线程的执行从而避免冲突。不过这种做法并不理想因为编写不当的代码可能会导致整个系统被阻塞让其他进程和线程都无法正常运行。此外如果系统有多个处理器这种做法也是行不通的因为其他线程可以在其他CPU上并行执行。互斥量的实现需要硬件的支持以便能够进行原子的测试和设置操作。通过这种操作某个执行单元可以检查内存中的值是否与预期相符如果相符它就会将内存中的值设置为“已锁定”状态。硬件确保了这一测试和设置操作的原子性——也就是说在操作完成之前其他执行单元无法访问该内存位置。早期的硬件实现方式是通过封锁整个总线来确保这种原子性这样其他处理器就无法同时使用该内存。如果另一个执行单元尝试进行同样的操作却发现内存已经被设置为“已锁定”状态那么操作系统会阻止该线程的继续执行直到内存状态再次变为“可用”为止。互斥锁与顺序处理当然当协程的数量超过两个时我们也可以使用互斥锁来解决同步问题。请注意使用互斥锁会限制程序的并发程度。在互斥锁被锁定和解锁之间的代码段任何时候都只能由一个协程来执行这样一来这段代码就变成了顺序执行的代码。正如我们在第一章中所看到的根据阿姆达尔定律顺序执行与并行执行的比例会限制代码的性能可扩展性。因此我们必须尽量减少互斥锁被占用的时间。如果在countLetters()函数开始时锁定互斥锁而在函数执行完毕后释放它会怎么样呢从下面的代码可以看出我们在调用该函数后立即锁定互斥锁而在输出完成后的消息后释放互斥锁。packagemainimport(fmtionet/httpstringssynctime)constAllLettersabcdefghijklmnopqrstuvwxyzfuncmain(){mutex:sync.Mutex{}varfrequencymake([]int,26)fori:1000;i1030;i{url:fmt.Sprintf(https://rfc-editor.org/rfc/rfc%d.txt,i)goCountLetters(url,frequency,mutex)}time.Sleep(60*time.Second)mutex.Lock()fori,c:rangeAllLetters{fmt.Printf(%c-%d ,c,frequency[i])}mutex.Unlock()}// CountLetters// Note: this program us locking the entire goroutine with mutex on purpose to demonstrate// bad placement of the lock and unlock. We fix this in the next listingfuncCountLetters(urlstring,frequency[]int,mutex*sync.Mutex){mutex.Lock()resp,_:http.Get(url)deferresp.Body.Close()ifresp.StatusCode!200{panic(Server returning error status code: resp.Status)}body,_:io.ReadAll(resp.Body)for_,b:rangebody{c:strings.ToLower(string(b))cIndex:strings.Index(AllLetters,c)ifcIndex0{frequency[cIndex]1}}fmt.Println(Completed:,url,time.Now().Format(15:04:05))mutex.Unlock()}通过这种方式使用互斥锁我们将原本的并发程序变成了顺序执行的程序。这样一来我们每次只能下载并处理一个网页因为整个程序的执行过程被无谓地阻塞了。如果继续运行这个程序其耗时将与非并发版本的程序相同只不过各网页的执行顺序会是随机的而已。下图展示了一种使用三个协程来实现这种锁定机制的简化调度示意图。从图中可以看出这些协程大部分时间都用于下载文档而用于处理文档的时间则相对较短。在图中我们刻意缩小了下载与处理之间所需时间的比例以便于说明问题。实际上两者之间的时间差距要大得多。总的来说协程们几乎把所有时间都用在了下载文档上而用于处理文档的时间则微乎其微。从性能角度来看没有必要让整个执行过程都被阻塞。因为文档下载过程与其他协程无关所以也就不存在发生竞争条件的风险。提示在决定何时以及如何使用互斥锁时我们应先明确需要保护哪些资源并确定各个临界区的起始点和结束点。之后我们需要想办法尽量减少“Lock()”和“Unlock()”调用的次数。packagelisting4_5import(fmtionet/httpstringssynctime)constAllLettersabcdefghijklmnopqrstuvwxyzfuncCountLetters(urlstring,frequency[]int,mutex*sync.Mutex){resp,_:http.Get(url)deferresp.Body.Close()ifresp.StatusCode!200{panic(Server returning error code: resp.Status)}body,_:io.ReadAll(resp.Body)mutex.Lock()for_,b:rangebody{c:strings.ToLower(string(b))cIndex:strings.Index(AllLetters,c)ifcIndex0{frequency[cIndex]1}}mutex.Unlock()fmt.Println(Completed:,url,time.Now().Format(15:04:05))}在这个代码版本中下载过程——也就是程序中耗时最长的部分——会以并行方式执行。而快速处理字母计数的任务则会在顺序模式下进行。通过这种方式我们能够最大限度地提升程序的可扩展性因为我们只对那些执行速度远远快于其他部分的代码段使用锁机制。程序的执行过程如图所示。同样为了便于观察下载和处理所需的时间比例被夸大了。实际上处理所需的时间远远少于下载网页所需的时间因此加速效果更为显著。实际上在我们的main()函数中可以将等待时间缩短到几秒钟左右之前是60秒。第二种解决方案比我们的第一次尝试要快得多。当锁定需要处理的代码量较小时我们完成任务的效率会更高。这里的经验法则是尽量减少持有互斥锁的时间同时也要减少互斥锁的调用次数。回想一下阿姆达尔定律就不难理解这一点如果代码中并行处理部分所占的时间更长那么整体处理速度就会更快系统的扩展性也会更好。非阻塞式互斥锁当一个协程调用 Lock() 函数时如果互斥锁已被其他协程占用那么该协程将会被阻塞。这就是所谓的“阻塞函数”该协程的执行会停止直到有另一个协程调用 Unlock() 函数为止。在某些应用中我们会……或许不必阻塞该协程而是可以先执行其他任务然后再尝试锁定互斥量并访问临界区。正因如此Go语言中的互斥锁提供了另一个名为TryLock()的函数。调用这个函数时我们可能会遇到两种结果之一• 锁是可用的这种情况下我们就能获取到它此时函数会返回布尔值“true”。• 该锁当前无法使用因为另一个协程正在使用这个互斥锁。因此该函数会立即返回返回值为布尔值“false”。非阻塞机制的用途在Go语言的1.18版本中新增了用于处理互斥锁的TryLock()函数。不过关于这种非阻塞调用方式的实用示例其实很少见。这是因为在Go中创建一个goroutine的成本远远低于在其他语言中创建内核级线程的成本。如果互斥锁不可用让goroutine做其他事情并没有太大意义。因为在这种情况下我们完全可以另开一个goroutine来执行任务而无需等待互斥锁被释放。实际上Go的互斥锁文档中也提到了这一点来源pkg.go.dev/sync#Mutex.TryLock。需要注意的是虽然确实存在正确使用TryLock的情况但这种情况相当罕见。通常来说使用TryLock往往意味着在多线程编程中存在更严重的问题。使用TryLock()的一个例子是当需要监控某个任务的执行进度时又不希望干扰该任务的正常进行。如果使用普通的Lock()机制由于系统中有很多其他goroutine也在试图获取锁那么就会给互斥锁带来不必要的负担而这一切都是为了实现监控功能而已。而使用TryLock()的话如果此时有别的goroutine正在占用互斥锁那么监控用的goroutine就可以选择稍后再试。这就好比去邮局处理一件不紧急的事务时看到门口排着长队就决定改天再来办理吧。我们可以修改我们的字母频率统计程序让主goroutine在下载数据和处理文档的过程中定期检查频率表的内容。packagemainimport(fmtionet/httpstringssynctime)funcmain(){mutex:sync.Mutex{}varfrequencymake([]int,26)fori:2000;i2200;i{url:fmt.Sprintf(https://rfc-editor.org/rfc/rfc%d.txt,i)goCountLetters(url,frequency,mutex)}fori:0;i100;i{time.Sleep(100*time.Millisecond)ifmutex.TryLock(){fori,c:rangeAllLetters{fmt.Printf(%c-%d ,c,frequency[i])}fmt.Println()mutex.Unlock()}else{fmt.Println(Mutex already being used)}}}constAllLettersabcdefghijklmnopqrstuvwxyzfuncCountLetters(urlstring,frequency[]int,mutex*sync.Mutex){resp,_:http.Get(url)deferresp.Body.Close()ifresp.StatusCode!200{panic(Server returning error code: resp.Status)}body,_:io.ReadAll(resp.Body)mutex.Lock()for_,b:rangebody{c:strings.ToLower(string(b))cIndex:strings.Index(AllLetters,c)ifcIndex0{frequency[cIndex]1}}mutex.Unlock()fmt.Println(Completed:,url,time.Now().Format(15:04:05))}当我们运行代码时可以从输出结果中看到main()协程试图获取锁以打印出频率表。有时它能成功获取锁并完成打印而有时则无法获取锁此时它需要等待100毫秒后再尝试一次。利用读写互斥锁提升性能有时候互斥锁的约束过于严格。可以把互斥锁看作是一种“粗暴”的工具它通过阻止多个线程同时执行来解决问题。在任何时刻都只能有一个goroutine能够进入受互斥锁保护的代码段。这种方式确实能有效避免竞争条件带来的问题但对于某些应用来说它可能会不必要地限制性能和可扩展性。读写互斥锁则是对标准互斥锁的一种改进只有在我们需要更新共享资源时它才会阻止其他线程的访问。使用读写互斥锁后那些以读取操作为主的程序的性能可以得到提升因为在这种情况下对共享数据的读取操作远远多于更新操作。Go语言中的读写互斥锁如果所有处理客户请求的协程都能以非独占的方式访问该数据结构那么它们就可以在需要时同时读取数据。这样可以提高性能因为这样多个仅负责读取共享数据的协程就能同时访问该数据。只有当需要更新数据时才会对共享数据的访问进行限制。在这个例子中数据的更新频率很低每秒几次而读取数据的频率则非常高每秒数千次。因此采用一种允许多个协程同时读取数据、但只能有单个协程进行写入的机制会更有利。这就是读写锁的作用。当我们只需读取共享资源而不对其进行修改时读写锁允许多个协程同时执行只读操作。而当我们需要修改共享资源时负责写入操作的协程会请求获得写锁从而实现对该资源的独占访问。这一原理在上图中有所体现图的左侧显示读锁允许多个协程同时进行读取操作但会阻止任何写入操作而在图的右侧一旦获得了写锁那么所有的读取和写入操作都会被阻止这与普通互斥锁的机制类似。总结• 互斥锁可以用来保护代码中的关键部分防止它们被同时执行。• 我们可以通过在关键代码段的开始处调用Lock()函数在结束处调用unLock()函数来使用互斥锁保护这些关键部分。• 如果锁定的时间过长那么原本可以并行执行的代码就会变成顺序执行从而降低性能。• 我们可以通过调用 TryLock() 函数来检测某个互斥锁是否已被锁定。• 读写互斥锁能够提升那些以读取操作为主的应用程序的性能。• 读写互斥锁允许多个读取者协程同时执行临界代码段同时确保只有单个写入者协程能够访问该资源。• 我们可以使用一个计数器以及两个普通的互斥锁来构建一种“以读取操作为主的读写互斥机制”。

相关文章:

go语言使用互斥锁进行同步

我们可以利用互斥锁来保护代码中的关键部分,从而确保每次只能有一个goroutine访问共享资源。这样一来,就能避免竞争条件的问题。几乎所有支持并发编程的语言中,都使用了类似互斥锁的机制。在本章中,我们首先会了解互斥锁的功能。之…...

Windows 笔记本低功耗优化指南:从系统配置到 BIOS 底层,根治关机跑电

三步根治关机掉电快、合盖耗电异常,从系统到 BIOS 彻底解决!很多 Windows 11 笔记本用户都遇到过这种情况:明明正常关机,第二天开机电池掉电 10%;合盖放包里,半天就掉电 20%,甚至直接关机。这种…...

使用 Python 快速接入 Taotoken 并调用多模型 API 的完整步骤

使用 Python 快速接入 Taotoken 并调用多模型 API 的完整步骤 1. 准备工作 在开始编写代码之前,您需要完成几个简单的准备工作。首先确保您拥有一个 Taotoken 账户,并在控制台中创建了 API Key。登录 Taotoken 平台后,可以在「API 密钥管理…...

为什么你的网盘下载总是卡在“蜗牛模式“?LinkSwift用JavaScript重新定义文件下载体验

为什么你的网盘下载总是卡在"蜗牛模式"?LinkSwift用JavaScript重新定义文件下载体验 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度…...

秒言输入法 | 毫秒级极速响应 懂你的AI语音输入法

链接:https://pan.quark.cn/s/88b1a0f87060依靠强大的 AI 模型,秒言能自动整理口语中的碎片化语言,修正语病,输出你真正想表达的文字。...

Chrome二维码插件:3分钟掌握跨设备分享的终极指南

Chrome二维码插件:3分钟掌握跨设备分享的终极指南 【免费下载链接】chrome-qrcode :zap: A Chrome plugin to Genrate QRCode of URL / Text, or Decode the QRcode in website. 一个Chrome浏览器插件,用于生成当前URL或者选中内容的二维码,同…...

SSD Booster.NET(SSD驱动器优化工具)

链接:https://pan.quark.cn/s/9d0ee0442715SSD Booster.NET是一款旨在优化和调整Windows系统以适配固态硬盘(SSD)的工具,目的是提升SSD的效率并维持其高性能。它为用户提供了一个便捷的方式来调整SSD驱动的重要设置。紧凑的用户界面:拥有复古…...

3步解决经典游戏联机难题:IPXWrapper让老游戏重获新生

3步解决经典游戏联机难题:IPXWrapper让老游戏重获新生 【免费下载链接】ipxwrapper 项目地址: https://gitcode.com/gh_mirrors/ip/ipxwrapper 还在为《星际争霸》《红色警戒2》《魔兽争霸2》等经典游戏无法在现代Windows系统上联机而烦恼吗?IPX…...

不懂这个,一人企业必死

一人企业必死局:搞不懂这个核心死穴,做代运营、智能体服务,轻则白干重则负债 作者:智能体架构师卢成 | Agent Architect | 意图工程卢成 今天不讲风口、不讲变现,只给所有做一人企业、做To B代运营、做智能体企业服务的…...

用 AI 智能体自动写代码、自动测代码、自动部署,全程零手动操作

前言 以前写代码:自己构思→敲代码→本地调试→改 Bug→打包→传服务器→配置环境→上线部署,一套流程耗几小时。 现在AI Agent 智能体可以做到:你只说需求一句话,智能体自动:需求分析 → 生成完整代码 → 自动写单元…...

Python 爬虫反爬突破:JS 逆向混淆与加密参数破解实战

前言 在前五篇反爬专栏中,完整覆盖了浏览器指纹、硬件特征、无头伪装、访问频率等环境层反爬对抗方案,而前端 JS 加密与代码混淆,是现阶段企业级站点最高频、最难绕过的核心反爬手段。主流平台不再单纯依赖环境检测拦截爬虫,而是…...

AI Agent 零基础入门,5 分钟搭建自己的数字员工

前言 2026 年是AI Agent(智能体)爆发元年,它不再是高深的技术名词,而是能自主思考、拆解任务、调用工具、自动执行的数字员工 —— 能帮你自动写周报、整理资料、监控数据、回复消息,甚至部署项目、运维服务器。 本文…...

Android 13 WMS源码解析:手把手带你画DisplayArea层级树(附避坑指南)

Android 13 WMS深度解析:从源码到可视化理解DisplayArea层级构建 在Android窗口系统的核心架构中,DisplayArea的层级树扮演着至关重要的角色。作为窗口管理的骨架,这棵树的构建过程直接决定了各类窗口的显示优先级和交互逻辑。本文将带您深入…...

uni-app项目里用Leaflet.js加载天地图,搞定安卓App兼容(附完整代码)

uni-app集成Leaflet.js加载天地图的安卓兼容方案实战 最近在开发一个需要集成天地图功能的uni-app项目时,发现官方map组件对天地图的支持有限,特别是在安卓端遇到了不少兼容性问题。经过一番摸索和实践,最终通过Leaflet.js结合renderjs的方案…...

Anno 1800 Mod Loader:游戏模组加载器深度解析与实战应用

Anno 1800 Mod Loader:游戏模组加载器深度解析与实战应用 【免费下载链接】anno1800-mod-loader The one and only mod loader for Anno 1800, supports loading of unpacked RDA files, XML merging and Python mods. 项目地址: https://gitcode.com/gh_mirrors/…...

三月七小助手:星穹铁道智能自动化终极指南,解放你的游戏时间

三月七小助手:星穹铁道智能自动化终极指南,解放你的游戏时间 【免费下载链接】March7thAssistant 崩坏:星穹铁道全自动 三月七小助手 项目地址: https://gitcode.com/gh_mirrors/ma/March7thAssistant 还在为《崩坏:星穹铁…...

CAT架构:跨模态Transformer在语音技术中的实践

1. CAT架构概述:音频与语言的Transformer桥梁 在语音技术领域,传统流水线式系统通常将语音识别(ASR)、自然语言处理(NLP)和语音合成(TTS)作为独立模块串联实现。这种架构存在误差累积…...

在Windows上轻松安装安卓应用:APK Installer完全指南

在Windows上轻松安装安卓应用:APK Installer完全指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 让我们探索一种全新的Windows安卓应用安装方式——APK…...

3步掌握Bili2text:B站视频转文字终极指南,让学习效率翻倍!

3步掌握Bili2text:B站视频转文字终极指南,让学习效率翻倍! 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 在信息爆炸的时…...

博德之门3模组管理器终极指南:如何轻松管理上百个游戏模组 [特殊字符]

博德之门3模组管理器终极指南:如何轻松管理上百个游戏模组 🎮 【免费下载链接】BG3ModManager A mod manager for Baldurs Gate 3. This is the only official source! 项目地址: https://gitcode.com/gh_mirrors/bg/BG3ModManager 你是否曾经因为…...

PicX Studio CLI:AI图像工作流的命令行自动化与集成实践

1. 项目概述:PicX Studio CLI,一个为AI图像工作流而生的命令行利器如果你和我一样,经常在终端里敲敲打打,同时又需要频繁地与AI图像生成服务打交道,那么你肯定能理解那种在浏览器、代码编辑器、文件管理器之间反复横跳…...

告别传统建模:如何用手机照片和Instant-NGP快速生成3D模型?

手机摄影革命:零代码实现高精度3D建模的NeRF实战指南 当我在2022年第一次用手机拍摄的20张玩具照片生成可360旋转的3D模型时,传统建模软件正在我的MacBook Pro上缓慢渲染一个简单几何体——这个对比让我意识到,计算机视觉领域正在发生一场静悄…...

3分钟搞定Jable视频下载:Chrome插件+一键保存全攻略

3分钟搞定Jable视频下载:Chrome插件一键保存全攻略 【免费下载链接】jable-download 方便下载jable的小工具 项目地址: https://gitcode.com/gh_mirrors/ja/jable-download 还在为无法保存Jable.tv上的精彩视频而烦恼吗?想要轻松将喜欢的视频下载…...

PKHeX自动化插件完整指南:告别手动调整,5分钟创建完美合法宝可梦

PKHeX自动化插件完整指南:告别手动调整,5分钟创建完美合法宝可梦 【免费下载链接】PKHeX-Plugins Plugins for PKHeX 项目地址: https://gitcode.com/gh_mirrors/pk/PKHeX-Plugins 还在为宝可梦数据合法性而烦恼吗?每次手动调整个体值…...

告别GitHub抽风!用OpenWRT的Crontab定时更新hosts,保姆级配置流程

告别GitHub抽风!用OpenWRT的Crontab定时更新hosts,保姆级配置流程 每次在关键时刻GitHub突然无法访问,是不是让你抓狂?作为开发者,我们经常需要从GitHub拉取代码、查阅文档,但网络不稳定成了拦路虎。手动修…...

实战解析:如何用AFLNet+Wireshark为Live555 RTSP服务器捕获并制作模糊测试种子(Pcap处理指南)

深度实战:基于AFLNet与Wireshark的RTSP协议模糊测试种子生成全流程 当安全研究员面对一个RTSP服务器时,如何快速构建有效的模糊测试环境?传统方法往往止步于工具安装,却忽略了最关键的一环——高质量种子输入的制备。本文将揭示从…...

从CFD新手到项目上手:我的第一个MATLAB流体仿真项目复盘(Simulink+Fluent实战)

从CFD新手到项目上手:我的第一个MATLAB流体仿真项目复盘 第一次打开MATLAB准备做流体仿真时,我盯着空白的Simulink界面发呆了十分钟。课堂上学过的纳维-斯托克斯方程突然变得无比抽象,而Fluent导出的.dat文件就像天书。这篇复盘记录了我从零开…...

天赐范式第30天:天赐范式19+原生算子流统一API白皮书——从微积分几何到宇宙学的全场景调用索引

与天赐范式已发布的代码实现,这样以后你们找起来就方便了。 天赐范式核心公式总纲(从微积分几何到宇宙学) 查阅说明:本文将天赐范式的核心公式分为八大类。每条公式后附有其在CSDN原文中的验证代码/伪代码片段,确保理论…...

LayerD:智能图层分离技术重塑图形设计流程

1. 项目概述:重新定义图形设计的层级编辑在数字设计领域,我们经常遇到一个经典难题:当客户发来一张JPG格式的平面设计稿,要求修改其中的某个元素时,设计师往往需要花费大量时间进行图像分离和重建。这正是LayerD试图解…...

在Windows上轻松安装APK文件:告别模拟器时代的轻量级解决方案

在Windows上轻松安装APK文件:告别模拟器时代的轻量级解决方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经在Windows电脑上收到一个APK文件却…...