多线程的几种方式
PThread
NSThread
CGD (Grand Center Dispatch)
NSOperation (NSInvaocationOperation / NSBlockOperation)
1.PThread
POSIX Thread(Portable Operation System Interface) 可移植的操作系统的接⼝口 ⼀一套通⽤用的多线程API;基于C语⾔言的接⼝口;难度较⼤大;⼏几乎不⽤用。
1.1使用PThread创建线程
步骤⼀:导⼊入pthread.h 头⽂文件
#impoet <pthread.h>
步骤二:创建⼦子线程对象pthread_t
pthread_t thread;
步骤三:提供线程执⾏行函数
void *task(void *data){......}
步骤四:创建⼦子线程,并执⾏行任务
pthread_create(&thread,
NULL, //线程属性 task,
task, //函数指针
NULL //传给函数指针的参数 );
NSThread
优势:基于OC接⼝口,使⽤用⽅方便
缺点:⼿手动管理线程的⽣生命周期
2.1使用NSThread创建线程
init方式创建
在需要的时候启动线程 需要手动启动
//线程执⾏行的⽅方法 -(void)downloadTask:(id)obj{
NSLog(@"当前线程:%@",[NSThread currentThread]); //模拟耗时操作
NSLog(@"%@",(NSString*)obj);

}
//使⽤用initWithTarget创建线程 -(void)createThreadByInit{
NSLog(@"主线程:%@",[NSThread currentThread]);
NSThread *thread=[[NSThread alloc]initWithTarget:self selector:@selector(downloadTask:) object:@"parameters"];
//启动线程的任务 //设定线程的⼀一些属性
thread.name=@"⼦子线程";//名字 thread.threadPriority=0.5;//优先级 [thread start];
NSLog(@"---------------");
}
其他用法
1.获取当前线程
[NSThread currentThread];
2.线程的调度优先级,调度优先级的取值范围是0.0 ~ 1.0,默认0.5,值越⼤大⼤大,优先级越⾼高
+ (double)threadPriority;
+ (BOOL)setThreadPriority:(double)p;
3.设置线程的名字
- (void)setName:(NSString *)n;
- (NSString *)name;
detach方式创建
//使⽤用detachNewThreadSelector创建线程 -(void)createThreadByDetach{
[NSThread detachNewThreadSelector:@selector(downloadTask:) toTarget:self withObject:@"parameter"];
}
perform方式
//使⽤用perform创建线程 -(void)createThreadByPerform{ //NSObject的实例⽅方法(self)
[self performSelector:@selector(downloadTask:) withObject:@"parameter"];
}
PS:
1.[NSThread currentThread]->{number = 1, name = main}:⼀一定是在主线程中被执⾏行 2.[NSThread currentThread]->{number = 2, name = (null)}:只要number不为1就是⼦子线程
3.使⽤用initWithTarget创建的线程需要使⽤用start启动。
4.使⽤用detachNewThreadSelector⾃自动创建线程并启动。
GCD
GCD的概念介绍
Crand Central Dispatch
特点:
1.不需要了解线程的内部运作原理
2.基于C语⾔言的接⼝口
3.利⽤用CPU多核的特点
4.GCD后端⾃自动管理着⼀一个线程池(重复利⽤用线程)
基本步骤:
1.创建空队列 (串⾏行队列 并⾏行队列)
2.把任务添加到队列
3.执⾏行队列中的任务(同步执⾏行 异步执⾏行)
GCD创建线程
- 串⾏行同步:队列中的任务顺序执⾏行;在当前线程中执⾏行
- 串⾏行异步:队列中的任务顺序执⾏行;在⼦子线程中执⾏行,主线程继续执⾏行不会等待⼦子线程执 ⾏行完毕
- 并⾏行同步(一般不⽤用):队列中的任务顺序执⾏行;在当前线程中执⾏行
- 并⾏行异步:队列中的任务同时执⾏行;在⼦子线程执⾏行;主线程继续执⾏行,不会等待⼦子线程执 ⾏行完毕
全局队列和主队列
全局队列:是全局的并行队列
主队列:是在主线程中的队列 (串行)
主队列不要执行同步任务 不然会导致阻塞
dispatch_once
static dispatch_once_t oneToken;
dispatch_once(&oneToken,^{
});
扩展:线程安全的单例模式
//使⽤用GCD dispatch_once
//适⽤用场景:多线程安全
static DataCenterManager *_dataCenterByGCD = nil;
+ (id)sharedDataCenterByGCD {
static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{
_dataCenterByGCD = [[DataCenterManager alloc] init]; });
return _dataCenterByGCD;
}
dispatch_group_async/dispatch_group_notify
//队列:全局队列
//执⾏行⽅方式:dispatch_group_async()
dispatch_queue_t globalQueue = dispatch_get_global_queue(0,0);
//把耗时的下载的图⽚片的任务加到全局队列中,以group为单位
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, globalQueue, ^{
[NSThread sleepForTimeInterval:4];
NSLog(@"第⼀一个图⽚片下载完毕:%@", [NSThread currentThread]);
dispatch_group_async(group, globalQueue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"第⼆二个图⽚片下载完毕:%@", [NSThread currentThread]); });
dispatch_group_async(group, globalQueue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"第三个图⽚片下载完毕:%@", [NSThread currentThread]); });
//通知三个图⽚片下载完毕
dispatch_group_notify(group, globalQueue, ^{
NSLog(@"三个图⽚片下载完毕:%@", [NSThread currentThread]); //回到主线程

 dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回到主线程更新UI界⾯面"); });
});
NSOperation
相对于GCD的优势是可以设置线程之间的依赖关系
常用概念
什么是线程,线程和进程有什么区别?
进程(process)是一块包含了某些资源的内存区域,操作系统利⽤用进程把它的⼯工作划分为
一些功能单元,一个应⽤用程序配套一个进程。 线程(thread)进程中所包含的一个或者多个执⾏行单元称为线程,线程负责执⾏行代码,一个 进程⾥里可以有多个线程。
并行队列和串行队列
串⾏行队列(Serial Dispatch Queue): 依次执⾏行队列中的线程
并⾏行队列(Concurrent Dispatch Queue): 同时执⾏行队列中的线程
同步和异步
同步(Synchronize)队列中的任务在当前线程中执⾏行(不会启动新的线程)。
异步(Asynchronize)队列中的任务在⼦子线程中执⾏行。
并行、并发
并发当有多个线程在操作时,如果系统只有⼀一个CPU,则它根本不可能真正同时进⾏行一个以上
的线程,它只能把CPU运⾏行时间划分成若干个时间段,再将时间 段分配给各个线程执⾏行,在 ⼀个时间段的线程代码运⾏行时,其它线程处于挂起状。.这种⽅方式我们称之为并发 (Concurrent)。
并行:当系统有一个以上CPU时,则线程的操作有可能⾮非并发。当一个CPU执⾏行一个线程 时,另一个CPU可以执⾏行另一个线程,两个线程互不抢占CPU资源,可以同时进⾏行,这种 ⽅方式我们称之为并⾏行(Parallel)。
临界区、临界资源
每个进程中访问临界资源的那段程序称为临界区(临界资源是⼀一次仅允许⼀一个进程使⽤用的共 享资源)。每次只准许⼀一个进程进⼊入临界区,进⼊入后不允许其他进程进⼊入。
死锁
所谓死锁: 是指两个或两个以上的进程在执⾏行过程中,由于竞争资源或者由于彼此通信⽽而
造成的一种阻塞的现象,若⽆无外⼒力作⽤用,它们都将⽆无法推进下去。此时称系统处于死锁状态
或系统产⽣生了死锁,这些永远在互相等待的进程称为死锁进程。