iOS底層原理系列04-并發編程

在移動應用開發中,流暢的用戶體驗至關重要,而并發編程是實現這一目標的關鍵技術。本文將深入探討iOS平臺上的并發編程和多線程架構,幫助你構建高性能、響應迅速的應用程序。

1. iOS線程調度機制

1.1 線程本質和iOS線程調度機制

線程是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。一個進程可以擁有多個線程,每個線程共享進程的資源,但擁有自己的執行路徑。

在iOS系統中,線程調度由系統內核負責,通過優先級隊列和時間片輪轉算法確定線程的執行順序和執行時長。蘋果對標準的線程模型進行了優化,引入了更高級的抽象,如GCD和Operation,使開發者能夠專注于任務本身,而非線程管理的細節。

1.2 并發計算模型中的同步/異步與串行/并行

并發編程中的兩組基本概念:同步/異步和串行/并行。這兩組概念看似簡單,但常被混淆,它們實際上描述了兩個不同的維度。

同步/異步的本質

同步(Synchronous)與異步(Asynchronous)描述的是調用方式,關注的是線程的等待方式

  • 同步調用:調用者會一直等待被調用的任務完成后,才繼續執行后續代碼。調用者線程在任務執行期間處于阻塞狀態。
  • 異步調用:調用者不會等待被調用的任務完成,會立即繼續執行后續代碼。任務的完成通常通過回調、通知或其他機制通知調用者。

串行/并行的本質

**串行(Serial)與并行(Concurrent)**描述的是任務的執行方式,關注的是多個任務之間的關系。

  • 串行執行:多個任務按順序依次執行,任何時刻只有一個任務在執行。
  • 并行執行:多個任務可以同時執行,任務之間相互獨立,各自在不同的線程上執行。

同步/異步與串行/并行排列組合的調度機制和執行效果

這兩組概念可以組合出四種不同的調度情況,下面我們詳細分析每種組合的調度機制和執行效果。

在這里插入圖片描述

1. 同步 + 串行

  • 調度機制:任務在當前線程上按順序執行
  • 執行效果:調用者線程被阻塞,直到所有任務完成

2. 同步 + 并行

  • 調度機制:任務被分配到多個線程并發執行
  • 執行效果:調用者線程仍然被阻塞,直到所有任務完成
  • 注意:這種組合在實際中較少使用,因為即使任務并行執行,調用者仍需等待所有任務完成,無法充分利用并行的優勢

3. 異步 + 串行

  • 調度機制:任務在另一個線程上按順序執行
  • 執行效果:調用者線程立即返回繼續執行后續代碼,不會被阻塞

4. 異步 + 并行

  • 調度機制:任務被分配到多個線程并發執行
  • 執行效果:調用者線程立即返回繼續執行后續代碼,不會被阻塞,同時多個任務可以同時執行,充分利用多核處理器性能

這四種組合方式構成了iOS多線程編程的基礎模型,也是理解GCD和NSOperation等高級API的關鍵。

2. iOS線程方案

iOS提供了多種多線程編程方案,從底層的pthread到高級的GCD和NSOperation,為開發者提供了靈活的選擇。

2.1 pthread

pthread(POSIX thread)是一套跨平臺的線程API標準,iOS也支持這一標準。它比NSThread更底層,提供了更多的控制選項。

#import <pthread.h>// 創建線程
pthread_t thread;
pthread_create(&thread, NULL, ThreadFunction, NULL);// 線程函數
void *ThreadFunction(void *data) {// 執行任務NSLog(@"任務在pthread中執行");return NULL;
}// 等待線程結束
pthread_join(thread, NULL);

優點

  • 跨平臺兼容性好
  • 控制粒度更細
  • 可以設置線程的各種屬性

缺點

  • API復雜,使用不便
  • 需要手動管理線程的各個方面
  • 缺乏Objective-C與iOS集成的便利特性

2.2 NSThread

NSThread是Objective-C中最基本的線程類,它是對pthread的面向對象封裝,提供了創建和管理線程的基本功能。

// 創建并啟動線程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];
thread.name = @"MyCustomThread";
[thread start];// 或者使用類方法創建并自動啟動線程
[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];

優點

  • 簡單直觀,面向對象的API
  • 可以直接控制線程的生命周期

缺點

  • 需要手動管理線程生命周期
  • 缺乏高級特性,如線程池、任務依賴等
  • 線程創建和銷毀的開銷較大

2.3 GCD

GCD是一個強大的并發編程框架,通過任務和隊列的概念簡化了多線程編程。GCD的核心思想是讓開發者關注"做什么"而不是"怎么做"。
在這里插入圖片描述

2.3.1 GCD的核心概念:

隊列(Queue):負責存儲和管理任務。

  • 串行隊列(Serial Queue):按順序執行任務。
  • 并行隊列(Concurrent Queue):可以同時執行多個任務。
  • 主隊列(Main Queue):在主線程上執行任務,通常用于UI更新。

任務(Task):以Block(代碼塊)形式提交到隊列。

調度方式

  • 同步調度(sync):等待任務完成后返回。
  • 異步調度(async):提交任務后立即返回。

下面是GCD的常見用法示例:

// 獲取全局并行隊列
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);// 異步執行任務
dispatch_async(globalQueue, ^{// 耗時操作NSData *data = [self fetchDataFromServer];// 在主隊列更新UIdispatch_async(dispatch_get_main_queue(), ^{[self updateUIWithData:data];});
});// 創建自定義串行隊列
dispatch_queue_t serialQueue = dispatch_queue_create("com.example.serialQueue", DISPATCH_QUEUE_SERIAL);// 同步執行任務
dispatch_sync(serialQueue, ^{// 這會阻塞當前線程直到該任務完成[self processData];
});

2.3.2 GCD其他高級功能

如分組(group)、信號量(semaphore)、一次性執行(once)等:

// 使用組管理多個任務
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);// 添加任務到組
dispatch_group_async(group, queue, ^{// 任務1
});
dispatch_group_async(group, queue, ^{// 任務2
});// 等待所有任務完成
dispatch_group_notify(group, dispatch_get_main_queue(), ^{NSLog(@"所有任務已完成");
});

優點

  • 簡潔高效的API
  • 自動管理線程池
  • 針對多核處理器優化
  • 低系統開銷

缺點

  • 相比NSOperation,不支持取消任務
  • 不支持任務優先級(舊版本)
  • 調試難度相對較高

2.4 NSOperation/NSOperationQueue

NSOperationNSOperationQueue是基于GCD構建的更高級的抽象,提供了面向對象的API和更強大的任務管理能力。

NSOperation是一個抽象類,開發者通常使用其子類:

  1. NSBlockOperation:用于執行一個或多個Block的操作。
  2. NSInvocationOperation:用于調用特定對象的選擇器。
  3. 自定義NSOperation子類:實現復雜任務邏輯。

NSOperationQueue用于管理和執行NSOperation對象:

// 創建隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 4; // 設置最大并發數// 創建操作
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{NSData *imageData = [self downloadImageData];UIImage *image = [UIImage imageWithData:imageData];// 在主隊列更新UI[[NSOperationQueue mainQueue] addOperationWithBlock:^{self.imageView.image = image;}];
}];// 添加完成回調
operation1.completionBlock = ^{NSLog(@"圖片下載完成");
};// 添加操作到隊列
[queue addOperation:operation1];

NSOperation/NSOperationQueue最強大的特性是可以設置操作之間的依賴關系,構建復雜的工作流:

// 創建多個操作
NSBlockOperation *downloadOp = [NSBlockOperation blockOperationWithBlock:^{// 下載圖片
}];NSBlockOperation *filterOp = [NSBlockOperation blockOperationWithBlock:^{// 過濾圖片
}];NSBlockOperation *saveOp = [NSBlockOperation blockOperationWithBlock:^{// 保存圖片
}];// 設置依賴關系
[filterOp addDependency:downloadOp]; // 先下載,再過濾
[saveOp addDependency:filterOp];     // 先過濾,再保存// 添加到隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperations:@[downloadOp, filterOp, saveOp] waitUntilFinished:NO];

NSOperation還支持任務的取消、暫停和恢復:

// 取消單個操作
[operation cancel];// 取消隊列中所有操作
[queue cancelAllOperations];// 暫停隊列
queue.suspended = YES;// 恢復隊列
queue.suspended = NO;

優點

  • 面向對象的API
  • 支持操作的取消、暫停和恢復
  • 支持操作優先級
  • 支持操作間依賴關系
  • 內置了完成塊(completionBlock)
  • KVO兼容,可以觀察操作狀態

缺點

  • 相比GCD,開銷略大
  • API相對復雜
  • 初始化和配置需要更多代碼

3. iOS中的線程安全方案

多線程編程中,一個關鍵問題是如何確保共享資源的訪問安全。iOS提供了多種鎖機制和同步方案,下面按性能從高到低介紹。

3.1 os_unfair_lock

這是iOS 10引入的鎖機制,用于替代已廢棄的OSSpinLock。它是一種低級互斥鎖,性能極高。

#import <os/lock.h>// 創建鎖
os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;// 加鎖
os_unfair_lock_lock(&lock);
// 臨界區代碼
os_unfair_lock_unlock(&lock);// 嘗試加鎖(非阻塞)
if (os_unfair_lock_trylock(&lock)) {// 加鎖成功,執行臨界區代碼os_unfair_lock_unlock(&lock);
} else {// 加鎖失敗
}

適用場景:需要高性能且臨界區操作簡短的場景。

3.2 OSSpinLock (已廢棄)

自旋鎖在等待鎖釋放時會持續嘗試獲取鎖,不會進入休眠狀態。雖然性能很高,但在iOS平臺上存在優先級反轉問題,已被蘋果廢棄。

#import <libkern/OSAtomic.h>// 創建鎖
OSSpinLock lock = OS_SPINLOCK_INIT;// 加鎖
OSSpinLockLock(&lock);
// 臨界區代碼
OSSpinLockUnlock(&lock);

注意:由于存在優先級反轉問題,不推薦使用,應改用os_unfair_lock。

3.3 dispatch_semaphore_t

信號量是一種計數器,可以用來控制訪問共享資源的線程數量。

// 創建信號量,初始值為1(表示互斥鎖)
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);// 等待(減1,如果結果小于0則等待)
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 臨界區代碼
// 釋放(加1,如果之前小于0則喚醒等待線程)
dispatch_semaphore_signal(semaphore);

適用場景:需要控制并發訪問數量的場景,不僅限于互斥訪問。

3.4 pthread_mutex

POSIX線程庫提供的互斥鎖,是一種通用的同步機制。

pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);// 加鎖
pthread_mutex_lock(&mutex);
// 臨界區代碼
pthread_mutex_unlock(&mutex);// 釋放鎖
pthread_mutex_destroy(&mutex);

適用場景:需要可靠互斥且對性能要求不極端高的通用場景。

3.5 dispatch_queue(DISPATCH_QUEUE_SERIAL)

串行隊列可以用作同步機制,確保任務按順序執行。

// 創建串行隊列
dispatch_queue_t queue = dispatch_queue_create("com.example.safeQueue", DISPATCH_QUEUE_SERIAL);// 同步執行(類似于加鎖)
dispatch_sync(queue, ^{// 臨界區代碼
});// 異步執行(非阻塞)
dispatch_async(queue, ^{// 臨界區代碼
});

適用場景:適合需要異步執行且保證順序的場景,更偏向任務編排而非簡單鎖定。

3.6 NSLock

Foundation框架提供的Objective-C互斥鎖類。

NSLock *lock = [[NSLock alloc] init];// 加鎖
[lock lock];
// 臨界區代碼
[lock unlock];// 嘗試加鎖(非阻塞)
if ([lock tryLock]) {// 加鎖成功[lock unlock];
}// 帶超時的加鎖
if ([lock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]]) {// 在1秒內獲取到鎖[lock unlock];
}

適用場景:需要面向對象API和超時功能的一般場景。

3.7 NSCondition

條件變量和互斥鎖的結合,用于線程間的等待和通知機制。

NSCondition *condition = [[NSCondition alloc] init];// 生產者線程
[condition lock];
// 修改共享數據
[condition signal]; // 或 [condition broadcast]
[condition unlock];// 消費者線程
[condition lock];
while (/* 條件不滿足 */) {[condition wait]; // 等待通知
}
// 臨界區代碼
[condition unlock];

適用場景:生產者-消費者模式等需要線程間通信的場景。

3.8 NSRecursiveLock

遞歸鎖允許同一線程多次獲取鎖,而不會導致死鎖。

NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];// 第一次加鎖
[lock lock];
// 可以再次獲取同一把鎖而不會死鎖
[lock lock];
// 臨界區代碼
[lock unlock];
[lock unlock]; // 需要平衡調用unlock

適用場景:需要在遞歸調用或嵌套調用中使用鎖的場景。

3.9 @synchronized

Objective-C提供的語言級同步原語,使用簡單但性能相對較低。

@synchronized(self) {// 臨界區代碼
}

適用場景:對性能要求不高的簡單同步場景,或原型開發。

3.10 原子屬性 (atomic) 實現原理

Objective-C中的屬性可以聲明為atomic,保證讀寫操作的原子性:

@property (atomic, strong) NSString *name;

實現原理:編譯器會為atomic屬性生成訪問器方法,使用自旋鎖/互斥鎖確保讀寫操作的原子性。

限制:atomic只保證單個屬性的讀寫原子性,不保證相關操作的原子性。例如,對數組的原子性讀寫不保證數組內容的訪問也是原子的。

3.11 讀寫安全方案

除了互斥鎖外,還有專門針對讀多寫少場景優化的讀寫鎖:

pthread_rwlock

讀寫鎖允許多個線程同時讀取共享資源,但寫操作需要獨占訪問。

pthread_rwlock_t rwlock;
pthread_rwlock_init(&rwlock, NULL);// 讀鎖(共享)
pthread_rwlock_rdlock(&rwlock);
// 讀取操作
pthread_rwlock_unlock(&rwlock);// 寫鎖(獨占)
pthread_rwlock_wrlock(&rwlock);
// 寫入操作
pthread_rwlock_unlock(&rwlock);// 銷毀鎖
pthread_rwlock_destroy(&rwlock);
dispatch_barrier_async:異步柵欄調用

GCD提供的柵欄函數可以用于實現高效的讀寫分離:

// 創建并發隊列
dispatch_queue_t queue = dispatch_queue_create("com.example.rwQueue", DISPATCH_QUEUE_CONCURRENT);// 讀操作(多個可并發執行)
dispatch_async(queue, ^{// 讀取操作
});// 寫操作(柵欄函數,保證獨占訪問)
dispatch_barrier_async(queue, ^{// 寫入操作
});

柵欄函數的工作原理是:

  1. 等待隊列中已有的任務完成
  2. 獨占式執行柵欄任務
  3. 柵欄任務完成后,后續的普通任務才能執行

這種方式非常適合讀多寫少的場景,能夠提供極高的并發性能。

4. 常見陷阱

4.1 死鎖情況及預防

死鎖發生在兩個或多個線程互相等待對方釋放鎖的情況。最常見的死鎖場景:

// 主線程
dispatch_sync(dispatch_get_main_queue(), ^{// 這會導致死鎖,因為主線程嘗試同步等待主隊列的任務,// 而主隊列的任務必須等待主線程完成當前執行
});

預防措施

  1. 避免在持有鎖時獲取另一個鎖
  2. 如需多個鎖,按固定順序獲取
  3. 使用帶超時的鎖獲取方式
  4. 避免在主線程上同步派發到主隊列
  5. 使用GCD的dispatch_group或信號量來協調多個異步操作

4.2 優先級反轉

當低優先級線程持有鎖,高優先級線程等待該鎖,而中優先級線程占用CPU時,高優先級線程會被無限期阻塞。

解決方案

  1. 使用優先級繼承的鎖機制
  2. 避免在臨界區執行耗時操作
  3. 使用合適的隊列優先級

4.3 主線程阻塞引起的UI卡頓

在主線程上執行耗時操作會導致UI無法響應,造成卡頓感:

// 錯誤示例: 主線程同步等待耗時操作
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://example.com/large-file.zip"]];

正確做法

  1. 將耗時操作移至后臺線程
  2. 使用異步API而非同步API
  3. 合理分解大任務為小任務
  4. 使用Instruments等工具監測和優化主線程性能
// 正確示例: 異步執行耗時操作,完成后回到主線程更新UI
dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://example.com/large-file.zip"]];dispatch_async(dispatch_get_main_queue(), ^{// 更新UI[self.imageView setImage:[UIImage imageWithData:data]];});
});

總結

iOS提供了多種并發編程和線程安全的機制,從底層的pthread到高級的GCD和NSOperation。選擇合適的機制需要考慮以下因素:

  1. 性能需求:對于性能要求極高的場景,考慮os_unfair_lock或dispatch_semaphore;對于一般場景,NSLock和串行隊列足夠。
  2. 編程范式:如果偏好面向對象的API,選擇NSOperation和NSLock系列;如果偏好函數式編程,選擇GCD。
  3. 任務特性:如果需要復雜的任務依賴和取消機制,選擇NSOperation;如果是簡單的并發任務,GCD更簡潔。
  4. 同步需求:讀多寫少場景推薦讀寫鎖或柵欄函數;需要線程通信的場景適合條件變量。

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

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

相關文章

Vmware下的openEuler

1.下載openEuler操作系統鏡像 https://repo.openeuler.org/openEuler-20.03-LTS/ISO/ 2.在VM新建虛擬機 3.虛擬機聯網 我是出現了沒有網絡&#xff0c;ping不通的問題 參考&#xff1a;https://blog.csdn.net/FHY26828/article/details/140941234 修改文件&#xff1a; 在…

帶寬管理配置實驗

一、實驗拓撲 配置流程&#xff1a; 1、帶寬通道&#xff1a;整體帶寬、每個用戶帶寬、連接數、優先級信息 2、帶寬策略 3、策略通道&#xff0c;引用 4、配置接口出入帶寬 二、實驗需求和配置 1、基礎配置 接口配置 [dianxin]interface GigabitEthernet 0/0/0 [dianxin-G…

【STM32】從新建一個工程開始:STM32 新建工程的詳細步驟

STM32 開發通常使用 Keil MDK、STM32CubeMX、IAR 等工具來創建和管理工程。此處是 使用 Keil MDK5 STM32CubeMX 創建 STM32 工程的詳細步驟。 新建的標準庫工程文件已上傳至資源中&#xff0c;下載后即可直接使用。 標準庫新建 STM32 工程的基本目錄結構&#xff1a;STD_STM…

探索 Trossen AI:從 Aloha到智能機器人平臺的進化之路

在人工智能與機器人技術快速發展的當下&#xff0c;科研硬件的性能與成本成為影響行業創新的重要因素。Trossen Robotic為在機器人領域二十余年的知名企業&#xff0c;近日推出的 Trossen AI 系列產品&#xff0c;為科研機構與開發者提供了高性能、高性價比的解決方案。 Trosse…

C語言:5.20程序練習題

打印一個菱形圖案。程序分為兩部分&#xff1a;上半部分和下半部分。上半部分打印一個逐漸增大的星號圖案&#xff0c;下半部分打印一個逐漸縮小的星號圖案。 #include<stdio.h> int main() {int row 5;//定義行數int t 2;for (int i row; 0 < i; i--){for (int k…

一些docker命令

一、基礎命令 查看 Docker 版本 docker --version 或 docker version&#xff1a;顯示 Docker 客戶端和服務器的版本信息。 查看 Docker 系統信息 docker info&#xff1a;顯示 Docker 系統的詳細信息&#xff0c;包括鏡像、容器數量、存儲驅動類型等。 Docker 服務管理 s…

C語言內容

C語言是一門經典且廣泛應用的編程語言&#xff0c;具有以下基礎要點&#xff1a; 基本數據類型 包括整型&#xff08;如 int &#xff09;、字符型&#xff08; char &#xff09;、浮點型&#xff08; float 和 double &#xff09;等&#xff0c;用于定義不同類型的變量來…

Python----數據可視化(Pyecharts一:介紹安裝,全局配置,系列配置)

一、PyEcharts介紹 1.1、概況 Echarts 是一個由百度開源的數據可視化&#xff0c;憑借著良好的交互性&#xff0c;精巧的圖表設計&#xff0c;得到了眾多開發者的認可。而 Python 是一門富有表達力的語言&#xff0c;很適合用于數據處理。當數據分析遇上數據可視化時&#xff…

dockerfile 編寫入門

Dockerfile編寫指南 Dockerfile是一個文本文件&#xff0c;其中包含了一系列的指令和參數&#xff0c;用于定義如何構建Docker鏡像。一個良好編寫的Dockerfile不僅可以確保鏡像的構建過程高效、可靠&#xff0c;還可以使得鏡像更加安全和易于維護。 1. Dockerfile基本結構和語…

Git 本地常見快捷操作

Git 本地常見快捷操作 &#x1f4cc; 1. 基本操作 操作命令初始化 Git 倉庫git init查看 Git 狀態git status添加所有文件到暫存區git add .添加指定文件git add <file>提交更改git commit -m "提交信息"修改最后一次提交信息git commit --amend -m "新…

如何處理PHP中的文件上傳錯誤

如何處理PHP中的文件上傳錯誤 在Web開發中&#xff0c;文件上傳是一個常見的功能需求。然而&#xff0c;文件上傳過程中可能會遇到各種錯誤&#xff0c;如文件大小超出限制、文件類型不被允許、上傳過程中斷等。為了確保用戶能夠順利上傳文件&#xff0c;并且開發者能夠有效地…

Linux--普通文件的管理

目錄 1、創建根目錄結構中的所有的普通文件 2、列出所有賬號的賬號名 3、將/etc/passwd中內容按照冒號隔開的第三個字符從大到小排序后輸出所有內容 4、列出/etc/passwd中的第20行-25行內容 head命令 tail命令 5、切割出你的ip地址和mac地址 ip地址 MAC地址 6、切割…

【SpringMVC】常用注解:@RequestBody

1.作用 用于獲取請求實體內容&#xff0c;直接使用得到的是keyvalue&keyvalue的數據。獲取請求實體內容不適用get請求。 2.屬性 required 描述是否有請求體&#xff0c;默認值為true。當取值為true時&#xff0c;get 請求方式會報錯。如果取值為false&#xff0c;get請…

RK3588 遠程 SSH時出現WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!

WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 翻譯過來就是 警告&#xff1a;遠程主機標識已更改&#xff01; 此報錯是由于遠程的主機的公鑰發生了變化導致的。 ssh服務是通過公鑰和私鑰來進行連接的&#xff0c;它會把每個曾經訪問過計算機或服務器的公鑰&#xff…

Go紅隊開發—web網絡編程

文章目錄 web網絡編程Req快速請求 調試DevModeDebugLogTraceInfo瓶頸分析 控制請求與響應控制請求的字段內容控制調試打印的內容分開dump請求與響應部分請求體設置 作用范圍級別設置參數查詢URL 路徑參數表單請求設置請求頭設置 判斷響應狀態碼解析數據SetSuccessResultgjson響…

PawSQL for TDSQL:騰訊云TDSQL數據庫性能優化全攻略

TDSQL 作為騰訊云推出的分布式數據庫&#xff0c;憑借其高擴展性、高可用性和高性能等優勢&#xff0c;廣泛應用于金融、互聯網、政務等領域。隨著業務的不斷增長和數據量的爆炸式增長&#xff0c;如何優化 TDSQL 數據庫的性能&#xff0c;成為眾多企業和開發者面臨的挑戰。本文…

67.Harmonyos NEXT 圖片預覽組件之性能優化策略

溫馨提示&#xff1a;本篇博客的詳細代碼已發布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下載運行哦&#xff01; Harmonyos NEXT 圖片預覽組件之性能優化策略 文章目錄 Harmonyos NEXT 圖片預覽組件之性能優化策略效果預覽一、性能優化概述1. 性能優化的關鍵指標…

C語言中的字符串與數組的關系

在C語言中,字符串和數組之間有著緊密的關系。理解它們的區別和聯系對于編寫高效且可靠的代碼至關重要。在本篇博文中,我們將詳細分析字符串和數組在C語言中的概念、它們的關系以及如何在編程中應用它們。 一、字符串與數組的基礎知識 1.1 數組概念 在C語言中,數組是一組相…

56.HarmonyOS NEXT 登錄模塊開發教程(十):總結與展望

溫馨提示&#xff1a;本篇博客的詳細代碼已發布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下載運行哦&#xff01; HarmonyOS NEXT 登錄模塊開發教程&#xff08;十&#xff09;&#xff1a;總結與展望 文章目錄 HarmonyOS NEXT 登錄模塊開發教程&#xff08;十&a…

添加 ChatGPT/Grok/Gemini 到瀏覽器搜索引擎

添加 ChatGPT/Grok/Gemini 到瀏覽器搜索引擎 添加 ChatGPT/Grok/Gemini 到瀏覽器搜索引擎如何添加步驟 1: 打開瀏覽器設置步驟 2: 添加新搜索引擎步驟 3: 保存設置 注意事項 添加 ChatGPT/Grok/Gemini 到瀏覽器搜索引擎 在使用 ChatGPT/Grok/Gemini 進行對話時&#xff0c;每次…