【iOS】多線程原理

目錄

前言

基本概念及原理

線程、進程與隊列

線程的定義:

進程的定義:

線程與進程之間的聯系與區別:

線程和runloop的關系

影響任務執行速度的因素

多線程

多線程生命周期

線程池的原理

iOS中多線程的實現方式

線程安全問題

互斥鎖

自旋鎖

對比GCD和NSOperation

NSThread

GCD

函數

隊列

函數與隊列的不同組合

串行隊列 + 同步派發

?編輯串行隊列 + 異步派發

?編輯

并發隊列 + 同步派發

?編輯

并發隊列 + 異步派發

主隊列 + 同步函數

主隊列 + 異步派發

dispatch_after

dispatch_once

dispatch_apply

dispatch_group_t

dispatch_group_async + dispatch_group_notify

dispatch_group_enter + dispatch_group_leave + dispatch_group_notify

dispatch_barrier_sync & dispatch_barrier_async

dispatch_semaphore_t

dispatch_source

NSOperation

NSInvocationOperation

NSBlockOperation

NSOperationQueue

設置優先級

設置并發數

設置依賴


前言

多線程在iOS的開發中起到了非常重要的作用,筆者在之前已經有學習過關于GCD的知識了,但是當時學得迷迷糊糊,正好借學習多線程底層原理的機會,來在學習多線程的同時對之前的知識做一個復習

基本概念及原理

線程、進程與隊列

線程的定義:
  • 線程是進程的基本執行單元,一個進程的所有任務都在線程中執行

  • 進程想要執行任務,必須得有線程,進程至少要有一條線程

  • 程序啟動會默認開啟一條線程,這條線程被成為主線程UI線程

進程的定義:
  • 進程是指在系統中正在運行的一個應用程序,如微信、支付寶app都是一個進程

  • 每個進程之間是獨立的,每個進程均運行在其專用的且受保護的內存空間內

通俗地說,可以理解為:進程是線程的容器,而線程用來執行任務。在iOS中是單進程開發,一個進程就是一個app,進程之間是相互獨立的,如支付寶、微信、qq等,這些都是屬于不同的進程。

線程與進程之間的聯系與區別:
  • 地址空間:同一進程線程共享本進程的地址空間,而進程之間則是獨立的地址空間

  • 資源擁有:同一進程內的線程共享本進程的資源如內存、I/O、cpu等,但是進程之間的資源是獨立的

  • 一個進程崩潰后,在保護模式下不會對其他進程產生影響,但是一個線程崩潰整個進程都死掉,所以多進程要比多線程健壯

  • 進程切換時,消耗的資源大、效率高.所以設計到頻繁的切換時,使用線程要好于進程。同樣如果要求同時進行并且又要共享某些變量的并發操作,只能用線程而不能用進程

  • 線程是處理器調度的基本單位,但進程不是

  • 線程沒有地址空間,線程包含在進程地址空間中

線程和runloop的關系
  • runloop與線程是一一對應的 —— 一個runloop對應一個核心的線程,為什么說是核心的,是因為runloop是可以嵌套的,但是核心的只能有一個,他們的關系保存在一個全局的字典里

  • runloop是來管理線程的 —— 當線程的runloop被開啟后,線程會在執行完任務后進入休眠狀態,有了任務就會被喚醒去執行任務

  • runloop在第一次獲取時被創建,在線程結束時被銷毀

    • 對于主線程來說,runloop在程序一啟動就默認創建好了

    • 對于子線程來說,runloop是懶加載的 —— 只有當我們使用的時候才會創建,所以在子線程用定時器要注意:確保子線程的runloop被創建,不然定時器不會回調

影響任務執行速度的因素

以下因素都會對任務的執行速度造成影響:

  • cpu的調度

  • 線程的執行速率

  • 隊列情況

  • 任務執行的復雜度

  • 任務的優先級

多線程

多線程生命周期

多線程的生命周期主要分為5部分:新建 - 就緒 - 運行 - 阻塞 - 死亡

  • 新建:實例化線程對象

  • 就緒:線程對象調用start方法,將線程對象加入可調度線程池等待CPU的調用,即調用start方法,并不會立即執行,進入就緒狀態,需要等待一段時間,經CPU調度后才執行,也就是從就緒狀態進入運行狀態

  • 運行:CPU 負責調度可調度線程池中線程的執行。在線程執行完成之前,其狀態可能會在就緒和運行之間來回切換.就緒和運行之間的狀態變化由CPU負責,程序員不能干預

  • 阻塞:當滿足某個預定條件時,可以使用休眠或鎖,阻塞線程執行。sleepForTimeInterval(休眠指定時長),sleepUntilDate(休眠到指定日期),@synchronized(self):(互斥鎖)

  • 死亡:正常死亡,即線程執行完畢。非正常死亡,即當滿足某個條件后,在線程內部(或者主線程中)終止執行(調用exit方法等退出)

處于運行中的線程擁有一段可以執行的時間(稱為時間片):

  • 如果時間片用盡,線程就會進入就緒狀態隊列

  • 如果時間片沒有用盡,且需要開始等待某事件,就會進入阻塞狀態隊列

  • 等待事件發生后,線程又會重新進入就緒狀態隊列

  • 每當一個線程離開運行,即執行完畢或者強制退出后,會重新從就緒狀態隊列選擇一個線程繼續執行

關于線程的exit和cancel方法:

  • exit:一旦強行終止線程,后續的所有代碼都不會執行

  • cancel:取消當前線程,但是不能取消正在執行的線程

線程池的原理

可以看到主要分為以下四步:

  1. 判斷核心線程池是否都正在執行任務:

    • 返回NO,創建新的工作線程去執行

    • 返回YES,進行第二步

  2. 判斷線程池工作隊列是否已經飽滿:

    • 返回NO,將任務存儲到工作隊列,等待CPU調度

    • 返回YES,進入第三步

  3. 判斷線程池中的線程是否都處于執行狀態

    • 返回NO,安排可調度線程池中空閑的線程去執行任務

    • 返回YES,進入第四步

  4. 交給飽和策略去執行,主要有以下四種:

    • AbortPolicy:直接拋出RejectedExecutionExeception異常來阻止系統正常運行

    • CallerRunsPolicy:將任務回退到調用者

    • DisOldestPolicy:丟掉等待最久的任務

    • DisCardPolicy:直接丟棄任務

iOS中多線程的實現方式

iOS中多線程的實現方式主要有四種:pthread、NSThread、GCD、NSOperation

線程安全問題

當多個線程同時訪問一塊內存,容易引發數據錯亂和數據安全問題,有以下兩種解決方案:

  • 互斥鎖(即同步鎖):@synchronized

  • 自旋鎖

互斥鎖
  • 保證鎖內的代碼,同一時間,只有一條線程能夠執行!

  • 互斥鎖的鎖定范圍,應該盡量小,鎖定范圍越大,效率越差!

  • 加了互斥鎖的代碼,當新線程訪問時,如果發現其他線程正在執行鎖定的代碼,新線程就會進入休眠

  • 能夠加鎖的是任意 NSObject 對象,但必須是 NSObject 對象

  • 鎖對象必須保證所有線程都能訪問

  • 單點加鎖時推薦使用 self

自旋鎖
  • 自旋鎖與互斥鎖類似,但它不是通過休眠使線程阻塞,而是在獲取鎖之前一直處于忙等(即原地打轉,稱為自旋)阻塞狀態

  • 使用場景:鎖持有的時間短,且線程不希望在重新調度上花太多成本時,就需要使用自旋鎖,屬性修飾符atomic,本身就有一把自旋鎖

  • 加入了自旋鎖,當新線程訪問代碼時,如果發現有其他線程正在鎖定代碼,新線程會用死循環的方法,一直等待鎖定的代碼執行完成,即不停的嘗試執行代碼,比較消耗性能

  • atomic 本身就有一把鎖(自旋鎖)

iOS開發的建議:

  • 所有屬性都聲明為 nonatomic

  • 盡量避免多線程搶奪同一塊資源 盡量將加鎖、資源搶奪的業務邏輯交給服務器端處理,減小移動客戶端的壓力

對比GCD和NSOperation

GCDNSOperation的關系如下:

  • GCD是面向底層的C語言的API

  • NSOperation是用GCD封裝構建的,是GCD的高級抽象

GCD和NSOperation的對比如下:

  • GCD執行效率更高,而且由于隊列中執行的是由block構成的任務,這是一個輕量級的數據結構 —— 寫起來更加方便

  • GCD只支持FIFO的隊列,而NSOpration可以設置最大并發數、設置優先級、添加依賴關系等調整執行順序

  • NSOpration甚至可以跨隊列設置依賴關系,但是GCD只能通過設置串行隊列,或者在隊列內添加barrier任務才能控制執行順序,較為復雜

  • NSOperation支持KVO(面向對象)可以檢測operation是否正在執行、是否結束、是否取消(如果是自定義的NSOperation 子類,需要手動觸發KVO通知)

NSThread

NSthread是蘋果官方提供面向對象的線程操作技術,是對thread的上層封裝,比較偏向于底層。

通過NSThread創建線程的方式主要有以下三種方式:

  • 通過init初始化方式創建

  • 通過detachNewThreadSelector構造器方式創建

  • 通過performSelector...方法創建,主要是用于獲取主線程,以及后臺線程

NSThread常用的類方法有以下:

  • currentThread:獲取當前線程

  • sleep...:阻塞線程

  • exit:退出線程

  • mainThread:獲取主線程

GCD

GCD就是Grand Central Dispatch,它是純 C 語言。關于GCD,筆者之前已經有博客詳細介紹過它的概念和接口以及用法了。這里對于GCD的簡單概念就不重復贅述了,詳情可以點擊筆者這篇博客——OC高級編程之GCD。這里就直接對GCD的函數與隊列來進行一個再梳理和復習吧

函數

GCD中執行任務的方式有兩種,同步執行異步執行,分別對應同步函數dispatch_sync異步函數dispatch_async

  • 同步執行,對應同步函數dispatch_sync

    • 必須等待當前語句執行完畢,才會執行下一條語句

    • 不會開啟線程,即不具備開啟新線程的能力

    • 在當前線程中執行block任務

  • 異步執行,對應異步函數dispatch_async

    • 不用等待當前語句執行完畢,就可以執行下一條語句

    • 會開啟線程執行block任務,即具備開啟新線程的能力(但并不一定開啟新線程,這個與任務所指定的隊列類型有關)

    • 異步是多線程的代名詞

綜上所述,兩種執行方式的主要區別有兩點:

  • 是否等待隊列的任務執行完畢

  • 是否具備開啟新線程的能力

隊列

多線程中所說的隊列Dispatch Queue)是指執行任務的等待隊列,即用來存放任務的隊列.隊列是一種特殊的線性表,遵循先進先出(FIFO)原則,即新任務總是被插入到隊尾,而任務的讀取從隊首開始讀取.每讀取一個任務,則動隊列中釋放一個任務。而隊列又分為串行隊列并發隊列

串行隊列:每次只有一個任務被執行,等待上一個任務執行完畢再執行下一個,即只開啟一個線程

并發隊列:一次可以并發執行多個任務,即開啟多個線程,并同時執行任務

函數與隊列的不同組合

串行隊列 + 同步派發

任務一個接一個地在當前線程執行,不會開辟新線程

串行隊列 + 異步派發

任務一個接一個地執行,但是會開辟新線程

并發隊列 + 同步派發

任務一個接一個地執行,不開辟線程

并發隊列 + 異步派發

任務亂序進行并且會開辟新線程

主隊列 + 同步函數

任務互相等待,造成死鎖

為什么這樣會造成死鎖,這里分析一下原因:

主隊列在執行任務執行到同步block時,會將block的任務加入到主隊列,但由于主隊列是串行隊列,因此block的任務要等主線程執行完block才可以執行(因為當前主線程中任務還沒有執行完,任務應該是進行到執行block了),而執行block其實就是執行block里的任務(即NSLog),主線程等著block里這個任務執行完才執行完,這樣就使得任務之間互相等待,從而造成了死鎖崩潰

死鎖

  • 主線程因為同步函數的原因等著先執行任務

  • 主隊列等著主線程的任務執行完畢再執行自己的任務

  • 主隊列和主線程相互等待會造成死鎖

主隊列 + 異步派發

主隊列是一個特殊的串行隊列,它雖然是串行隊列,但是其異步派發不會開辟新線程,而是將任務安排到主線程的下一個運行循環(Run Loop)周期執行

dispatch_after

dispatch_after表示在隊列中的block延遲執行,確切地說是延遲將block加入到隊列

dispatch_once

dispatch_once可以保證在app運行期間,block中的代碼只執行一次,可以用來創建單例

dispatch_apply

dispatch_apply將指定的block追加到指定的隊列中重復執行,并等到全部的處理執行結束(相當于線程安全的for循環)

應用場景:在拉取網絡數據后提前計算出各個控件的大小,防止繪制時計算,提高表單滑動流暢性

dispatch_group_t

dispatch_group_t:調度組將任務分組執行,能監聽任務組完成,并設置等待時間

應用場景:多個接口請求之后刷新頁面

dispatch_group_async + dispatch_group_notify

dispatch_group_notifydispatch_group_async執行結束之后會受收到通知

dispatch_group_enter + dispatch_group_leave + dispatch_group_notify

dispatch_group_enterdispatch_group_leave成對出現,使進出組的邏輯更加清晰

在此基礎上還可以使用 dispatch_group_wait

這里dispatch_group_wait這個函數第一個參數表示要等待的調度組,第二個參數表示要等多久(如果設置為DISPATCH_TIME_NOW表示不等待直接判定是否執行完畢,如果設置為DISPATCH_TIME_FOREVER表示阻塞當前調度組直到調度組執行完畢)

這個函數的返回值為long類型,如果返回值為0,表示在指定時間內調度組完成了任務;如果不為0,表示在指定時間內調度組沒有按時完成任務

dispatch_barrier_sync & dispatch_barrier_async

柵欄函數,主要使用在并發隊列,串行隊列使用柵欄函數沒什么意義。

柵欄函數即:等柵欄前追加到隊列中的任務執行完畢后,再將柵欄后的任務追加到隊列中。 簡而言之,就是先執行柵欄前任務,再執行柵欄任務,最后執行柵欄后任務

可以看到如果沒有柵欄,按照主線程的派發順序,任務2延遲1s,任務1延遲2s,應該是先完成任務2再完成任務1的,但是因為這里有柵欄函數,所以這里任務執行的順序變為:先執行柵欄前的任務1,再執行柵欄任務,然后執行柵欄后的任務2

  • dispatch_barrier_syncdispatch_barrier_async的作用相同,區別在于是否阻塞線程

注意??

1.盡量使用自定義的并發隊列

  • 使用全局隊列起不到柵欄函數的作用

  • 使用全局隊列時由于對全局隊列造成堵塞,可能致使系統其他調用全局隊列的地方也堵塞從而導致崩潰(并不是只有你在使用這個隊列)

2.柵欄函數只能控制同一并發隊列:打個比方,平時在使用AFNetworking做網絡請求時為什么不能用柵欄函數起到同步鎖堵塞的效果,因為AFNetworking內部有自己的隊列(也就是說柵欄函數不能跨隊列作用)

dispatch_semaphore_t

dispatch_semaphore_t表示信號量,可以用來控制GCD最大并發數

  • dispatch_semaphore_create():創建信號量

  • dispatch_semaphore_wait():等待信號量,信號量減1。當信號量< 0時會阻塞當前線程,根據傳入的等待時間決定接下來的操作——如果永久等待將等到信號(signal)才執行下去

  • dispatch_semaphore_signal():釋放信號量,信號量加1。當信號量>= 0 會執行wait之后的代碼

比如用信號量來代替柵欄函數使這段代碼按序輸出:

使用信號量的API來改寫的話就是這樣的:

如果當創建信號量時傳入值為1又會怎么樣呢?

  • i=0時有可能先打印,也可能會先發出wait信號量-1,但是wait之后信號量為0不會阻塞線程,所以進入i=1

  • i=1時有可能先打印,也可能會先發出wait信號量-1,但是wait之后信號量為-1阻塞線程,等待signal再執行下去

結論:

  • 創建信號量時傳入值為1時,可以通過兩次才堵塞

  • 傳入值為2時,可以通過三次才堵塞

dispatch_source

dispatch_source是一種基本的數據類型,可以用來監聽一些底層的系統事件

  • Timer Dispatch Source:定時器事件源,用來生成周期性的通知或回調

  • Signal Dispatch Source:監聽信號事件源,當有UNIX信號發生時會通知

  • Descriptor Dispatch Source:監聽文件或socket事件源,當文件或socket數據發生變化時會通知

  • Process Dispatch Source:監聽進程事件源,與進程相關的事件通知

  • Mach port Dispatch Source:監聽Mach端口事件源

  • Custom Dispatch Source:監聽自定義事件源

主要使用的API:

  • dispatch_source_create: 創建事件源

  • dispatch_source_set_event_handler: 設置數據源回調

  • dispatch_source_merge_data: 設置事件源數據

  • dispatch_source_get_data: 獲取事件源數據

  • dispatch_resume: 繼續

  • dispatch_suspend: 掛起

  • dispatch_cancle: 取消

比如通過dispatch_source來實現定時器,在開發中經常使用NSTimer來實現定時邏輯,但是NSTimier是依賴Runloop的,而Runloop可以運行在不同的模式下,如果NSTimer添加在一一種模式下,而Runloop運行在其他模式下,定時器就掛起了;又如果Runloop在阻塞狀態,那么NSTimer的觸發時間就會推遲到下一個Runloop周。因此NSTimer在計時上會有誤差,而GCD計時器不依賴Runloop,計時精度高很多

需要注意??:

  • GCDTimer需要強持有,否則出了作用域立即釋放,也就沒有了事件回調

  • GCDTimer默認是掛起狀態,需要手動激活

  • GCDTimer沒有repeat,需要封裝來增加標志位控制

  • GCDTimer如果存在循環引用,使用weak+strong或者提前調用dispatch_source_cancel取消timer

  • dispatch_resumedispatch_suspend調用次數需要平衡

  • source掛起狀態下,如果直接設置source = nil或者重新創建source都會造成crash。正確的方式是在激活狀態下調用dispatch_source_cancel(source)釋放當前的source

NSOperation

NSOperation是個抽象類,依賴于子類NSInvocationOperationNSBlockOperation去實現

NSInvocationOperation

也可以直接處理事務,不添加隱性隊列

NSBlockOperation

NSInvocationOperationNSBlockOperation兩者的區別在于:

  • 前者類似target形式

  • 后者類似block形式——函數式編程,業務邏輯代碼可讀性更高

NSOperationQueue是異步執行的,所以任務一任務二的完成順序不確定

通過addExecutionBlock這個方法可以讓NSBlockOperation實現多線程

NSBlockOperation創建時block中的任務是在主線程執行,而運用addExecutionBlock加入的任務是在子線程執行的(準確地來說,創建時block中的任務在start調用發生的線程執行)(當Operation沒有添加到隊列,而是通過start調用時)

NSOperationQueue

NSOperationQueue有兩種隊列:主隊列、其他隊列

  • 主隊列:主隊列上的任務是在主線程執行的

  • 其他隊列(非主隊列):加入到非主隊列中的任務默認就是并發,開啟多線程

通過類方法mainQueue可以得到主隊列

設置優先級

NSOperation設置優先級只會讓CPU有更高的幾率調用,不是說設置高就一定全部先完成

通過以下是否讓高優先級任務休眠的任務執行順序即可看出這一點:

不使用sleep:

使用sleep:

設置并發數

在NSOperation中不需使用信號量,直接設置maxConcurrentOperationCount就可以控制并發數,來控制單次出隊列去執行的任務數

設置依賴

NSOperation中添加依賴能很好的控制任務執行的先后順序

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/93319.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/93319.shtml
英文地址,請注明出處:http://en.pswp.cn/web/93319.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

藥房發藥的“時間密碼”:同步時鐘用藥安全?

在醫院的藥房里&#xff0c;每一粒藥片的流轉都暗藏“時間密碼”。從藥品入庫到患者服藥&#xff0c;時間記錄的精確性直接關乎生命安全。一旦時間數據出現偏差&#xff0c;輕則導致用藥爭議&#xff0c;重則引發醫療事故。近年來&#xff0c;隨著醫療數字化進程加速&#xff0…

UI-TARS-Desktop 深度解析:下一代智能自動化桌面平臺

目錄 1. 產品概述 2. 核心功能與技術架構 2.1 關鍵技術 2.2 功能亮點 3. 競品對比分析 4. 部署與成本分析 4.1 部署方案 4.2 隱性成本 5. 商業化前景 5.1 目標市場 5.2 盈利模式 5.3 風險挑戰 6. 未來演進方向 7. 總結 1. 產品概述 UI-TARS-Desktop 是一款基于A…

STM32L051同時處理Alarm A和Alarm B中斷

同時處理Alarm A和Alarm B中斷 當同時啟用Alarm A和Alarm B時&#xff0c;需要在中斷處理程序中準確判斷是哪個鬧鐘觸發了中斷。以下是完整的解決方案&#xff1a; 中斷判斷與處理流程 1. 在RTC中斷服務程序中判斷中斷源 // stm32l0xx_it.c void RTC_IRQHandler(void) {/* USER…

OpenCV---morphologyEx形態學操作

在計算機視覺與圖像處理領域&#xff0c;形態學操作是一種基于圖像形狀的非線性處理方法&#xff0c;廣泛應用于噪聲去除、邊緣檢測、目標分割等任務。OpenCV提供的morphologyEx函數是形態學操作的“瑞士軍刀”&#xff0c;它整合了多種高級形態學運算&#xff0c;能夠實現開運…

RuoYi-Cloud 接入 Sentinel 的 3 種限流方式

場景&#xff1a; 服務&#xff1a;ruoyi-robot&#xff08;對外接口統一在 /external/gs/**&#xff09; 網關&#xff1a;ruoyi-gateway&#xff08;轉發到 ruoyi-robot&#xff09; 注冊/配置&#xff1a;Nacos 流控&#xff1a;Sentinel 1.8.x 控制臺 Dashboard&#x…

快速搭建python HTTP Server測試環境

這里用python http.server搭建一個api測試環境&#xff0c;自定義請求處理程序&#xff0c;以模擬不同api相應。 1 服務代碼 /api/data&#xff0c;端口8000&#xff0c;GET 返回json數據為"{"message": "This is a sample API response"}" 代…

Docker容器定時任務時區Bug導致業務異常的環境變量配置解決方案

Docker容器定時任務時區Bug導致業務異常的環境變量配置解決方案 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般絢爛的技術棧中&#xff0c;我是那個永不停歇的色彩收集者。 &#x1f98b; 每一個優化都是我培育的花朵&#xff0c;每一個特性都是…

解鎖Dify與MySQL的深度融合:MCP魔法開啟數據新旅程

文章目錄解鎖Dify與MySQL的深度融合&#xff1a;MCP魔法開啟數據新旅程引言&#xff1a;技術融合的奇妙開篇認識主角&#xff1a;Dify、MCP 與 MySQL&#xff08;一&#xff09;Dify&#xff1a;大語言模型應用開發利器&#xff08;二&#xff09;MCP&#xff1a;連接的橋梁&am…

雜記 02

1 WSL安裝 WSL的安裝遇到了問題&#xff0c;睡醒起來發現電腦藍屏了&#xff0c;linux系統沒裝好&#xff0c;但是好像大部分開發環境都是linux下需要的&#xff0c;先這樣用一下吧&#xff0c;到時候再說。可以問下前輩開發細節&#xff0c;主要是網絡代理問題&#xff0c;保…

劇本殺小程序系統開發:重構推理娛樂生態

在娛樂產業蓬勃發展的今天&#xff0c;推理娛樂作為一種充滿智慧和挑戰的娛樂形式&#xff0c;受到了越來越多人的喜愛。劇本殺&#xff0c;作為推理娛樂的代表之一&#xff0c;正以其獨特的魅力吸引著大量玩家。而劇本殺小程序系統開發&#xff0c;則為推理娛樂生態的重構帶來…

力扣習題:基本計算器

本片內容我們將針對于一個力扣中的一道很經典的習題&#xff1a;基本計算器。 這道題目十分經典&#xff0c;在很多大廠的面試題中都有出現過 因此我們將進一步來學習 該題目代碼已經上傳作者的個人gitee&#xff1a;CPP 學習代碼庫: C代碼庫新庫&#xff0c;舊有C倉庫滿員了喜…

Element用法---Loading 加載

僅供參考 文章目錄一、加載動畫二、Loading 組件1、指令調用 Loading2、服務調用 Loading一、加載動畫 當我們打開某個頁面時&#xff0c;如果需要加載的數據很多或者網絡很差&#xff0c;頁面加載就會非常緩慢&#xff0c;中間可能會很長時間顯示空白&#xff0c;那么就需要加…

飛算AI 3.2.0實戰評測:10分鐘搭建企業級RBAC權限系統

飛算AI 3.2.0實戰評測&#xff1a;10分鐘搭建企業級RBAC權限系統 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般絢爛的技術棧中&#xff0c;我是那個永不停歇的色彩收集者。 &#x1f98b; 每一個優化都是我培育的花朵&#xff0c;每一個特性都…

事務的四大特性

事務&#xff08;Transaction&#xff09;是數據庫管理系統&#xff08;DBMS&#xff09;中用于保證數據操作正確性和一致性的核心機制。事務的特性通常用 ACID 四個字母概括&#xff0c;分別代表 原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consistency&…

WIN11系統下Open3D 0.19.0支持GPU的python版本

前往Open 3D官網下載https://github.com/isl-org/Open3D下載對應版本的源碼。 根據官方手冊利用cmake進行編譯&安裝&#xff0c;其中需要修改一些代碼適應于win 11系統&#xff0c;編譯時間較長需要耐心等待。最后&#xff0c;安裝結果如下圖&#xff0c;搞了四天&#xff…

ICCV 2025 | 4相機干掉480機位?CMU MonoFusion高斯潑濺重構4D人體!

???? 近日&#xff0c;卡內基梅隆大學&#xff08;Carnegie Mellon University&#xff09;的研究團隊在動態場景重建領域取得重要進展。其發表于ICCV 2025的論文《MonoFusion: Sparse-View 4D Reconstruction via Monocular Fusion》提出創新方法MonoFusion 。該方法突破常…

ADB 無線調試連接(Windows + WSL 環境)

gradle wrapper --gradle-version 8.4 Windows WSL 成功連接 Android 設備&#xff08;用于 ./gradlew installDebug&#xff09;的完整過程總結&#xff1a;? ADB 無線調試連接過程&#xff08;Windows WSL 環境&#xff09; &#x1f4cc; 目標&#xff1a;從 WSL 中通過 …

【.net core】【wetercloud】處理前端項目免登陸,且從前端項目跳轉至系統內時的問題

1.前端項目訪問后臺內容時免登陸&#xff08;一般用于后臺接口需要校驗登陸時&#xff09;處理思路&#xff1a;將后臺用戶的登陸校驗令牌信息在用戶登錄后添加至前端項目訪問地址的參數列表中&#xff0c;如&#xff1a;https://yourdomain/Home/Index#/https://yourdomain/vi…

設備 AI 知識庫,管理效率新飛躍

在設備管理領域&#xff0c;高效解決設備故障、合理規劃維護工作對企業生產運營至關重要。易點易動設備管理系統新推出的設備 AI 知識庫&#xff0c;為提升管理效率帶來了新契機。設備 AI 知識庫集成先進的人工智能技術&#xff0c;是設備管理領域的創新應用。易點易動設備管理…

C#繪制斐波那契螺旋

Fabonacci 數列&#xff0c;也就是”兔子數列“&#xff0c; 如果第一項為0的話&#xff0c;就是&#xff0c; 0&#xff0c;1&#xff0c;1&#xff0c;2&#xff0c;3&#xff0c;5&#xff0c;8&#xff0c;13&#xff0c;21&#xff0c;34&#xff0c;55&#xff0c;89……