ios多线程之GCD

在iOS中每个进程启动后都会建立一个主线程(UI线程),这个线程是其他线程的父线程。由于在iOS中除了主线程,其他子线程是独立于Cocoa Touch的,所以只有主线程可以更新UI界面(新版iOS中,使用其他线程更新UI可能也能成功,但是不推荐)。iOS中多线程使用并不复杂,关键是如何控制好各个线程的执行顺序、处理好资源竞争问题。常用的多线程开发有三种方式:

1.NSThread

2.NSOperation

3.GCD

今天我们来谈一谈GCD,这在以后的开发中最常用的。

我的IOS 交流群626433463

一、GCD基本概念

GCD 全称Grand Central Dispatch(大中枢队列调度),是一套低层API,提供了⼀种新的方法来进⾏并发程序编写。从基本功能上讲,GCD有点像NSOperationQueue,他们都允许程序将任务切分为多个单一任务,然后提交⾄⼯作队列来并发的或者串⾏的执行。GCD是C实现,⽐NSOpertionQueue更底层更高效,并且它不是Cocoa框架的一部分 并发任务会像NSOperationQueue那样基于系统负载来合适地并发进⾏,而串⾏行队列同一时间只执行单一任务,GCD的API很大程度上基于block。

GCD并发编程的主要好处归纳

GCD可用于多核的并行运算

GCD会自动利用更多的CPU内核(比如双核、四核)

GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)

程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

ios多线程之GCD_第1张图片

二、GCD如何实现

GCD主要由队列和任务两部分来实现,苹果官方对GCD是这样说明的:开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中。Dispatch Queue是执行处理的等待队列,我们可以通过dispatch_async等API,在block语法中记述想要执行的处理并将其追加到Dispatch Queue中,Dispatch Queue是按照追加的顺序进行处理(先进先出FIFO)。

说到GCD,必须强调队列和任务两个词,很多人容易搞混(当然,本人一开始接触ios也是一样懵逼),队列其实就跟物理课上的串联,并联电路差不多吧,任务就是同异步之分,同步不开启线程,异步开启新线程。这里就简单明了的说下吧:

队列:

串行队列:在队列中多个线程中有序进行;

并行队列:在队列中多个线程同时进行,没有顺序;

任务:

同步: sync ,它会阻塞当前线程,等待队列中的任务执行完毕,然后当前线程才会继续;

异步:async,不会阻塞线程,会直接往下执行;

代码:

1.主线程队列:

主线程异步队列中,也是顺序执行的,主线程中有任务,必须等主线程中的任务执行完毕才执行主队列,如果主线程中使用同步队列将会导致线程锁死,这点要注意,锁死的原因是循环等待,主队列的东西要等主线程执行完,而因为同步执行不能开线程,所以下面的任务要等上面的任务执行完,所以锁死。

//主异步:在主线程中顺序执行

dispatch_queue_t main = dispatch_get_main_queue();

for (int i = 0; i < 10; i++) {

dispatch_async(main, ^{

NSLog(@"主队列,异步%@",[NSThread currentThread]);

});

}

}

//主同步:会造成线程锁死

dispatch_queue_t main = dispatch_get_main_queue();

for (int i = 0; i < 0; i++) {

dispatch_sync(main, ^{

NSLog(@"你这是要锁死我%@",[NSThread currentThread]);

});

}

2.串行队列:

//串行同步:不开线程,在当前线程中有序的进行

dispatch_queue_t queue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);

for (int i = 0; i < 10; i++) {

dispatch_sync(cxTongB, ^{

NSLog(@"串行队列,同步%@",[NSThread currentThread]);

});

}

//串行异步:开启一条线程,然后有序的执行

dispatch_queue_t queue = dispatch_queue_create("YIBU", DISPATCH_QUEUE_SERIAL);

for (int i = 0; i < 10; i++) {

dispatch_async(queue, ^{

NSLog(@"串行队列,异步%@",[NSThread currentThread]);

});

}

3.并行队列

//并行同步:不开启线程,在当前线程有序进行

dispatch_queue_t bxtongbu = dispatch_queue_create("bxtongbu", DISPATCH_QUEUE_CONCURRENT);

for (int i = 0; i < 10; i++) {

//同步执行

dispatch_sync(bxtongbu, ^{

NSLog(@"并行队列,同步%@",[NSThread currentThread]);

});

}

//并行异步:开启多条线程,并发执行

dispatch_queue_t queue = dispatch_queue_create("bxYibu", DISPATCH_QUEUE_CONCURRENT);

for (int i = 0; i < 10 ; i++) {

dispatch_sync(queue, ^{

NSLog(@"并行队列,异步%@",[NSThread currentThread]);

});

}

总结:

ios多线程之GCD_第2张图片

1. 开不开线程,取决于执行任务的函数,同步不开,异步开。

2. 开几条线程,取决于队列,串行开一条,并发开多条(异步)

3. 主队列:专门用来在主线程上调度任务的"队列",主队列不能在其他线程中调度任务

4. 如果主线程上当前正在有执行的任务,主队列暂时不会调度任务的执行!主队列同步任务,会造成死锁。原因是循环等待

5. 同步任务可以队列调度多个异步任务前,指定一个同步任务,让所有的异步任务,等待同步任务执行完成,这是依赖关系。

6. 全局队列:并发,能够调度多个线程,执行效率高,但是相对费电。 串行队列效率较低,省电省流量,或者是任务之间需要依赖也可以使用串行队列。

7. 也可以通过判断当前用户的网络环境来决定开的线程数。

你可能感兴趣的:(ios多线程之GCD)