iOS多線程總結(jié)

******************************************************************************************
                                           pthread
******************************************************************************************

pthread 使用方法

pthread是C語言的多線程庫,使用pthread需要首先添加頭文件<pthread.h>

1. 聲明和實現(xiàn)一個函數(shù)
void *task(void *param){
    // 執(zhí)行任務(wù)的代碼
    return NULL;
}

2. 在合適的位置開啟多線程執(zhí)行之前聲明的函數(shù)
// 聲明一個線程
pthread_t thread; 
// 調(diào)用線程函數(shù)
pthread_create(&thread, NULL, task, NULL);

3. 判斷兩個線程是否相同的函數(shù)
pthread_equal(threadA, threadB);
******************************************************************************************
                                           NSThread
******************************************************************************************

NSThread 使用方法

NSThread 是OC的方法,封裝了pthread沮脖,使操作更加面向?qū)ο蟆?/p>

NSThread的方法
// 創(chuàng)建線程的方法
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@(task) object:nil];
// 設(shè)置線程名稱
thread.name = @"線程方法";
// 設(shè)置線程優(yōu)先級
thread.threadPriority = 0.0-1.0;  // 默認0.5
// 啟動線程
[thread start];
**************************************************************
// 使用分離的方法獲得線程
[NSThread detachNewThreadSelector:@selector(task) toTarget:self withObject:nil];
**************************************************************
// 開啟一條后臺的線程
[self performSelectInBackground:@selector(task) withObject:nil];
**************************************************************
// 獲得主線程
NSThread *mainThread = [NSThread mainThread];
**************************************************************
// 獲得當前線程
NSThread *currentThread = [NSThread currentThread];
**************************************************************
線程的操作方法
// start方法  new -> runabled
[thread start];

// 線程進入阻塞狀態(tài) run -> blocked
[NSThread sleepUntilDate:date];
[NSThread sleepForTimeInterval:timeInterval];

// 強制停止線程
[NSThread exit];
使用線程鎖
@synchronized(self){
    // 為了防止死鎖,使用線程鎖可以讓線程訪問一塊資源的時候為它加上鎖。
    // 一般使用self饲鄙,必須是全局唯一的對象凄诞。
    // 加鎖的代碼
}
線程之間的通信
// 線程通信是直接調(diào)用主線程的方法
[self performSelectorOnMainThread:@selector(task) withObject:nil waitUntilDone:YES/NO];
// 最后一個參數(shù)指是否等待task完成再執(zhí)行后面的代碼。

// 判斷當前線程是否為主線程
BOOL isMainThread = [[NSThread currentThread] isMainThread];
******************************************************************************************
                                           GCD
******************************************************************************************

GCD: Grand Central Dispatch

GCD 能夠充分利用CPU多核進行并行運算

創(chuàng)建隊列

1. 創(chuàng)建并發(fā)隊列 Concurrent Dispatch Queue
dispatch_queue_t queue = dispatch_queue_create("com.baidu.download", DISPATCH_QUEUE_CONCURRENT);

2. 獲得全局并發(fā)隊列
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
{ // 第一個參數(shù)是優(yōu)先級
    DISPATCH_QUEUE_PRIORITY_HIGH
    DISPATCH_QUEUE_PRIORITY_DEFAULT
    DISPATCH_QUEUE_PRIORITY_LOW  
    DISPATCH_QUEUE_PRIORITY_BACKGROUND
}

3. 創(chuàng)建串行隊列 Serial Dispatch Queue
dispatch_queue_t queue = dispatch_queue_create("com.baidu.download", DISPATCH_QUEUE_SERIAL)

4. 獲得主隊列 UI線程 (全局串行隊列)
dispatch_queue_t queue = dispatch_get_main_queue();

創(chuàng)建函數(shù)

1. 同步函數(shù)  // queue不能使用主隊列忍级,不然會產(chǎn)生死鎖帆谍。
dispatch_sync(queue, block);

2. 異步函數(shù)
dispatch_async(queue, block);

GCD常用函數(shù)

1. 延遲執(zhí)行代碼的方法 // 第一個參數(shù)指從現(xiàn)在開始, 第二個參數(shù)指兩秒后開始
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{...});

2. 一次性代碼: 單例demo
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{...});

3. 柵欄函數(shù) // queue不能使用全局并發(fā)隊列
dispatch_barrier_async(queue, ^{...});

4. 快速迭代代碼 // 第一個參數(shù)是迭代次數(shù) ,
// 第二個參數(shù)使用并發(fā)隊列轴咱,如果使用串行隊列就沒有意義了.
dispatch_apply(n, queue, ^(size_t i){...});

隊列組函數(shù)

// 創(chuàng)建隊列組
dispatch_group_t group = dispatch_group_create();
// 執(zhí)行隊列組函數(shù)
dispatch_group_async(group, queue, ^{...});

// 監(jiān)聽隊列組函數(shù)是否執(zhí)行完畢,組內(nèi)線程執(zhí)行完畢后執(zhí)行自己的函數(shù)
// 這個函數(shù)是異步執(zhí)行的汛蝙,不會阻塞后續(xù)代碼執(zhí)行
dispatch_group_notify(group, queue, ^{...});
// wait函數(shù)會阻塞線程,直到隊列組任務(wù)結(jié)束
dispatch_group_Wait(group, DISPATCH_TIME_FOREVER);
******************************************************************************************
                                           NSOperation
******************************************************************************************

NSOperation

NSOperation 是個抽象類朴肺,與NSOperationQueue搭配使用時可以開啟多線程窖剑。它有兩個子類,NSInvocationOperation 和 NSBlockOperation戈稿。

使用方法: 封裝操作 --> 添加到隊列西土。

封裝操作的方法
// 使用NSInvocationOperation封裝操作并啟動。這時候不會開線程
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task) object:nil];

[operation start];

****************************************************************
// 使用NSBlockOperation封裝操作鞍盗。封裝的操作不會開啟線程
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{...}];

// NSBlockOperation有一個追加操作的方法需了,追加的操作會自動開啟線程執(zhí)行。
[operation addExecutionBlock:^{...}];

[operation start];

****************************************************************
// 自定義[操作]
// 自定義一個繼承自NSOperation的類般甲,重寫main方法肋乍,將操作放到main方法中,使用init方法創(chuàng)建出來后可以直接添加到隊列中執(zhí)行操作敷存。
//*****main方法中存放需要封裝的耗時操作*****
添加到隊列
// NSOperation里有兩種隊列墓造,主隊列和非主隊列。
// 主隊列獲得方法
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
****************************************************************
// 非主隊列只能創(chuàng)建,init出來的隊列默認為非主隊列锚烦。
NSOperationQueue *queue = [[NSOperationQueue alloc]
 init];
 
// 操作非主隊列的maxConcurrentOperationCount屬性可以實現(xiàn)并發(fā)和串行的模式
// ****當i=1的時候滔岳,隊列也會開多條線程,但是多個操作在不同線程中會串行執(zhí)行****
// 當i=0時表示最大并發(fā)數(shù)為0挽牢,不會開啟線程則不會執(zhí)行操作
// i=-1谱煤,默認值,表示最大值禽拔。
queue.maxConcurrentOperationCount = (NSInteger)i; 
 
// 將任務(wù)添加到隊列刘离,隊列會自動調(diào)用任務(wù)的start方法并且開啟線程
[queue addOperation:operation];

****************************************************************
// 隊列可以使用快捷添加操作的方法
[queue addOperationWithBlock:^{}];
控制隊列內(nèi)操作的方法
// 操作的暫停和繼續(xù)
// ***已經(jīng)開始的線程是無法暫停的***
queue.suspended = YES; // 暫停操作
queue.suspended = NO; // 開始操作

**************************************************************** 
// 取消操作
// ***已經(jīng)開始的操作是無法取消的,取消后無法再次啟動***
// 因為耗時操作執(zhí)行時間太長睹栖,導致取消操作后已經(jīng)啟動的線程還在繼續(xù)執(zhí)行硫惕,可以使用在多個
// 位置添加代碼判斷是否取消了操作溺忧,提升用戶體驗.
// cancelAllOperations方法是調(diào)用所有操作的cancel方法,所以使用以下代碼
// *** if(self.isCancelled) return; ***[添加到耗時操作內(nèi)部隨時判斷]
[queue cancelAllOperations];

****************************************************************
// 控制操作的執(zhí)行順序

// 使用依賴的方法控制每個操作的執(zhí)行順序避诽,注意不能產(chǎn)生循環(huán)以來。
// ***即使操作在不同的隊列植捎,也可以跨隊列添加依賴關(guān)系***
[operationA addDependency:operationB];
// 執(zhí)行完B之后才會執(zhí)行A

// 使用監(jiān)聽的方法控制操作的執(zhí)行順序
// A執(zhí)行完畢后才會進入block執(zhí)行,block的代碼系統(tǒng)會自動開啟多線程執(zhí)行豁辉。
operationA.completionBlock = ^{...};【異步執(zhí)行】
線程之間的通信
// NSOperation的線程間通信可以直接使用隊列調(diào)用方法
// 在非主隊列中調(diào)用主隊列操作可以直接在非主隊列操作中調(diào)用方法:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{...}];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末令野,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子徽级,更是在濱河造成了極大的恐慌气破,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件餐抢,死亡現(xiàn)場離奇詭異现使,居然都是意外死亡,警方通過查閱死者的電腦和手機旷痕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門碳锈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人欺抗,你說我怎么就攤上這事殴胧。” “怎么了佩迟?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長竿屹。 經(jīng)常有香客問我报强,道長,這世上最難降的妖魔是什么拱燃? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任秉溉,我火速辦了婚禮,結(jié)果婚禮上碗誉,老公的妹妹穿的比我還像新娘召嘶。我一直安慰自己,他們只是感情好哮缺,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布弄跌。 她就那樣靜靜地躺著,像睡著了一般尝苇。 火紅的嫁衣襯著肌膚如雪铛只。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天糠溜,我揣著相機與錄音淳玩,去河邊找鬼。 笑死非竿,一個胖子當著我的面吹牛蜕着,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播红柱,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼承匣,長吁一口氣:“原來是場噩夢啊……” “哼蓖乘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起悄雅,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤驱敲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后宽闲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體众眨,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年容诬,在試婚紗的時候發(fā)現(xiàn)自己被綠了娩梨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡览徒,死狀恐怖狈定,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情习蓬,我是刑警寧澤纽什,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站躲叼,受9級特大地震影響芦缰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜枫慷,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一让蕾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧或听,春花似錦探孝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至足丢,卻和暖如春元镀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背霎桅。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工栖疑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滔驶。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓遇革,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子萝快,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 進程 什么是進程 進程是指在系統(tǒng)中正在運行的一個應(yīng)用程序 每個進程之間是獨立的锻霎,每個進程均運行在其專用且受保護的內(nèi)...
    45b645c5912e閱讀 466評論 0 5
  • 目錄 簡述 NSThread GCD操作與隊列異步操作并行隊列同步操作并行隊列同步操作串行隊列異步操作串行隊列隊列...
    魚王00閱讀 497評論 0 2
  • 多線程基本概念 單核CPU,同一時間cpu只能處理1個線程,只有1個線程在執(zhí)行 揪漩。多線程同時執(zhí)行:是CPU快速的在...
    WeiHing閱讀 702評論 1 5
  • 看到第六集旋恼,我才對電視劇有了一些了解。 我突然意識到奄容,三十五歲的男主冰更,他,代表了日本的宅男啊昂勒,他不是自己一個人蜀细,他...
    真愛521閱讀 435評論 0 0
  • 你經(jīng)歷過被家長催相親、催婚嗎戈盈? 或是好不容易放假回家了卻被身邊的親戚問東問西嗎奠衔? 相信這些都會帶來不愉快的心情。 ...
    90后的書生閱讀 213評論 0 0