進(jìn)程
1.正在進(jìn)行的一個(gè)過(guò)程或任務(wù),負(fù)責(zé)任務(wù)執(zhí)行的是cpu。
2.每個(gè)進(jìn)程之間是獨(dú)立的,每個(gè)進(jìn)程都運(yùn)行在獨(dú)立的內(nèi)存空間內(nèi),并擁有獨(dú)立運(yùn)行所需的全部資源。
線程
1.程序運(yùn)行時(shí)的最小單位,是進(jìn)程的實(shí)際運(yùn)作單位。
2.進(jìn)程想要執(zhí)行任務(wù)必須至少有一個(gè)線程。在應(yīng)用程序啟動(dòng)時(shí),系統(tǒng)會(huì)默認(rèn)開(kāi)啟一個(gè)線程,即主線程。
進(jìn)程和線程的關(guān)系
1.線程在進(jìn)程下進(jìn)行
2.一個(gè)進(jìn)程可以包含多個(gè)線程
3.同一個(gè)進(jìn)程內(nèi)不同的線程間數(shù)據(jù)容易共享
4.進(jìn)程是用內(nèi)存地址可以上鎖,即一個(gè)線程使用共享內(nèi)存時(shí),其他線程必須等待其結(jié)束,才能使用。(互斥鎖)
5.進(jìn)程使用的內(nèi)存地址也可以限定使用,即當(dāng)前只允許2 人訪問(wèn),第三人需要等待有人結(jié)束訪問(wèn)后再進(jìn)行訪問(wèn)。(信號(hào)量)
6.一個(gè)程序有多個(gè)進(jìn)程,一個(gè)進(jìn)程可以有多個(gè)線程,但每個(gè)進(jìn)程至少要有一個(gè)線程。
多線程
1.多條線程并發(fā)執(zhí)行,cpu快速的在多條線程之間調(diào)度。 如果cpu調(diào)度線程時(shí)間足夠的快,就造成了多線程并發(fā)的假象。
2.如果線程非常多,也會(huì)大量消耗cpu資源。
3.多線程可以提高程序的執(zhí)行效率,能適當(dāng)提高資源的利用率。
4.如果開(kāi)啟大量的線程會(huì)占用內(nèi)存空間,降低程序性能。
隊(duì)列
串行隊(duì)列
同一時(shí)間內(nèi),隊(duì)列中只能執(zhí)行一個(gè)任務(wù),當(dāng)前任務(wù)結(jié)束后才能執(zhí)行下一個(gè)任務(wù)。
并發(fā)隊(duì)列
同時(shí)允許多個(gè)任務(wù)并發(fā)執(zhí)行。
iOS中的多線程
GCD
1.獲取主線程
dispatch_queue_t main_queue = dispatch_get_main();
2.線程延時(shí)
/**
DISPATCH_TIME_NOW : 現(xiàn)在
DISPATCH_TIME_FOREVER : 永遠(yuǎn)超時(shí)
NSEC_PER_SEC : 秒 (1000,000,000 納秒 = 1秒) 可精確到納秒級(jí),eg. 0.1 * NSEC_PER_SEC 是0.1 * 1000,000,000 = 100,000,000 納秒 = 0.1秒 以下算法雷同。
NSEC_PER_MSEC : 毫秒 (1000,000 納秒 = 1 毫秒)可精確到毫秒級(jí)
USEC_PER_SEC : 秒 (1000000微秒 = 1秒) 可精確到微秒級(jí)
NSEC_PER_USEC : 微秒 (1000納秒 = 1 微秒) 可精確到納秒級(jí)
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC), main_queue, ^{
NSLog(@"哈哈");
})
3.只執(zhí)行一次,常用作單例模式
static dispatch_once_t once;
dispatch_once(&once, ^{
// 只實(shí)例化一次
personModel = [[self alloc] init];
});
4.線程組,即等待一組任務(wù)完成后繼續(xù)執(zhí)行下一步,常被應(yīng)用在圖片上傳
// 開(kāi)啟全集并發(fā)線程,DISPATCH_QUEUE_PRIORITY_DEFAULT 是線程等級(jí), 0 是flag,備用字段,通常設(shè)置0
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
// 進(jìn)行操作1
});
dispatch_group_async(group, queue, ^{
// 進(jìn)行操作2
});
dispatch_group_async(group, queue, ^{
// 進(jìn)行操作3
});
dispatch_group_notify(group, queue, ^{
// 操作1。2。3 執(zhí)行完畢 進(jìn)行 下一步操作
});
// 超時(shí)等待,即設(shè)置一個(gè)最長(zhǎng)等待時(shí)常,超過(guò)時(shí)間后 調(diào)起 notify block
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
5.信號(hào)量,設(shè)置最大并發(fā)線程數(shù),設(shè)置數(shù)大于1時(shí)順序不能保證
//創(chuàng)建信號(hào)量, 2為設(shè)置最大并發(fā)線程
dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
for (int i = 0; i < 5; i++) {
// 創(chuàng)建異步線程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 信號(hào)量的等待時(shí)長(zhǎng),這里設(shè)置為一直等待,當(dāng)信號(hào)量小于0 時(shí)一直等待,如果大于1則進(jìn)入且降低信號(hào)量即-1
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
// 睡眠2秒
sleep(2);
// po 出當(dāng)前線程, 顯示log
NSLog(@"%@", [NSThread currentThread]);
// 標(biāo)記信號(hào)量 + 1
dispatch_semaphore_signal(semaphore);
});
}
for (int i = 0; i < 5; i++) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
sleep(2);
NSLog(@"%@", [NSThread currentThread]);
dispatch_semaphore_signal(semaphore);
});
}
NSOPeration
NSOperation是基于GCD的抽象基類(lèi)。
NSOperation可以跨隊(duì)列設(shè)置依賴(lài)關(guān)系
NSOperation面向?qū)ο?,支持KVO,可以檢測(cè)operation是否正在執(zhí)行,是否結(jié)束或者取消
NSOperation實(shí)體子類(lèi)有兩個(gè),NSBlockOperation 和 NSInvocationOperation
// 初始化 方法實(shí)例
NSInvocationOperation *invoOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(haha:) object:nil];
[invoOperation start];
// 初始化 block塊 實(shí)例
NSBlockOperation *blockOpertaion = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"ni hao ");
}];
// 繼續(xù)添加線程
blockOperation add
[blockOpertaion start];
// 以下為 依賴(lài)關(guān)系
// 獲取 主線程
NSOperationQueue *main_Operation = [NSOperationQueue mainQueue];
// 創(chuàng)建 各種線程
NSOperation *person_a = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"我是 神秘人 A");
}];
NSOperation *person_b = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"我是 神秘人 B");
}];
NSOperation *person_c = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"我是 神秘人 C");
}];
// 添加依賴(lài)關(guān)系, A以來(lái) B和C ,相當(dāng)于 A要在 B C 之后才能執(zhí)行任務(wù)
[person_a addDependency:person_b];
[person_a addDependency:person_c];
//添加到 主線程中 查看順序
[main_Operation addOperation:person_a];
[main_Operation addOperation:person_b];
[main_Operation addOperation:person_c];
NSThread
NSThread使用比較簡(jiǎn)單,可以靜態(tài)獲取線程信息
// 獲取主線程
NSThread *thread = [NSThread mainThread];
// 判斷是否開(kāi)啟了多線程
BOOL isOpenThread = [NSThread isMultiThreaded];
// 獲取當(dāng)前線程
NSThread *currentThread = [NSThread currentThread];
// 當(dāng)前線程睡眠 時(shí)間(s) 10秒鐘
[NSThread sleepForTimeInterval:10];
// 睡眠到指定時(shí)間 , 以下為當(dāng)前時(shí)間往后延10秒鐘
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:10]];
// 退出當(dāng)前線程 , 禁止在主線程使用
//[NSThread exit];
// 初始化線程對(duì)象 實(shí)例化對(duì)象
/*
qualityOfService 線程的優(yōu)先級(jí)
NSQualityOfServiceUserInteractive 最高級(jí)別,用于UI交互,點(diǎn)擊事件,繪制圖形等
NSQualityOfServiceUserInitiated = 次高級(jí)別,用于執(zhí)行立即返回的任務(wù)
NSQualityOfServiceUtility 普通級(jí)別,不需要立即返回的任務(wù)
NSQualityOfServiceBackground 后臺(tái)級(jí)別,完全不緊急的任務(wù)
NSQualityOfServiceDefault 默認(rèn)級(jí)別
*/
NSLog(@"%@", [NSThread currentThread]);
NSThread *asynThread = [[NSThread alloc] initWithTarget:self selector:@selector(hello) object:nil];
// 設(shè)置 線程實(shí)例化對(duì)象的 優(yōu)先級(jí)別,默認(rèn)為 默認(rèn)級(jí)別
asynThread.qualityOfService = NSQualityOfServiceDefault;
// 開(kāi)始線程
[asynThread start];
// 也可以快速創(chuàng)建線程
[NSThread detachNewThreadSelector:@selector(hello) toTarget:self withObject:nil];
__weak typeof(self) weakSelf = self;
[NSThread detachNewThreadWithBlock:^{
// po 出當(dāng)前線程
NSLog(@"%@", [NSThread currentThread]);
// 回到主線程
[weakSelf performSelectorOnMainThread:@selector(hello) withObject:nil waitUntilDone:NO];
}];
// 還有一些 創(chuàng)建線程的方法
// 3 秒后執(zhí)行 hello 方法 , 在當(dāng)前線程
[self performSelector:@selector(hello) withObject:nil afterDelay:3];
// 后臺(tái)異步執(zhí)行
[self performSelectorInBackground:@selector(hello) withObject:nil];
// 在主線程上執(zhí)行 hello 方法
[self performSelectorOnMainThread:@selector(hello) withObject:nil waitUntilDone:NO];
// 在 指定的 asynThread 線程上執(zhí)行 hello方法 *** 注意避免在子線程中執(zhí)行 ui交互
[self performSelector:@selector(hello) onThread:asynThread withObject:nil waitUntilDone:NO];