多线程简介及GCD的使用

多线程简介:

对于任意一个iOS应用,程序运行起来后,默认会产生一个主线程(MainThread),主线程专门用来处理UIKit对象的操作,如界面的显示与更新、处理用户事件触发的操作等等。(记忆这点,所有与UI相关的操作都要在主线程中进行)

对于一个App应用来说,之所以需要引入多个线程,很大程度上是由于有一些操作是非常耗时的,例如:发送网络请求并等待服务器的响应,这种耗时操作是不能 够放在主线程中进行操作的,因为在等待的时间内,主线程被使用,用户是不能做任何交互动作的,因而会极大影响用户体验。对于耗时的操作,需要再另外创建一 个线程,放到后台处理,当处理完成得到结果后,再返回主线程去设置UI界面,这就涉及到线程间通信的相关知识。

那什么是GCD呢?

GCD(Grand Central Dispatch)技术,苹果首先应用于OSX中,随后在iOS中也引入了GCD技术。特别是苹果手机把CPU升级为多核后,GCD的使用变得更加广泛和 重要。相比于NSThread, GCD中已经完全屏蔽了有关线程的概念,而是引入了任务和队列,把任务放到队列中执行,制定任务和队列的类型,有关线程管理的事务完全交由GCD来处理, 大大简化了多任务开发的难度。在GCD中,程序员已经不再需要去关心有关线程的操作(如:线程创建、线程销毁、线程调度),而是引入了任务和队列两个核心概念。

由于GCD对线程管理进行了封装,因此,当工程师使用GCD时,只需要把任务(通常封装在一个block中)添加到一个队列中执行,有关线程调度的工作,完全交由GCD完成。

在使用GCD处理多任务执行时,只要按照如下步骤执行即可,

  • 在block中定义需要执行的任务内容;
  • 把任务添加到队列queue中

GCD对队列中的任务,按照“先进先出”的原则,根据任务添加到队列的顺序来对队列进行处理,GCD会根据任务和队列的类型,自动在多个线程之间分配工作。

GCD中,队列是一个重要概念。系统提供了若干预定义的队列,其中包括可以获取应用程序的主队列(任务始终在主线程上执行,UI操作需要在主队列中完成)。

GCD队列严格按照“先进先出”的原则,添加到GCD队列中的任务,始终会按照加入队列的顺序被执行。

GCD中最常见的是串行队列和并行队列:

  1. 并行队列:并行队列中的任务可以在多个线程之间分配执行,分配的原则由GCD控制,因此,并行队列中的任务,虽然分配执行时按照先进先出进行分配的,但由于各个任务被分配到不同的线程执行,因此其完成时间有可能不同,即:后分配的任务有可能先执行完成;并发队列一定需要和异步执行的任务(使用 dispatch_async())结合起来使用才有意义。
  2. 串行队列:串行队列中的任务是按照顺序一个一个完成的,当一个任务完成后,才去执行下一个任务;因此,串行队列对应一个线程执行。
  3. 主队列:主队列也是一个串行队列,主队列中的任务都在主线程中执行。

接下来用代码来清晰的展示GCD的功能.

 1     //CGD以队列的形式进行操作的,特点:"先进先出"
 2 #pragma mark - 使用GCD去创建一个串行队列
 3     //第一种:系统提供的创建串行队列的方法(主线程main)
 4     dispatch_queue_t queue = dispatch_get_main_queue();
 5     //真正的开发中如果需要创建串行队列,比较习惯用这种
 6     //第二种:自己去创建(串行队列:SERIAL)
 7     //参数一:是系统提供的一个宏
 8     //参数二:是系统的保留字段
 9     //两个参数的位置没有严格的限定,只要写这个两个参数即可
10     dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_SERIAL, 0);
11
12 #pragma mark - 使用GCD创建并行队列
13 //第一种方式(全局并行队列)
14     //参数一:优先级(有四个,没有明显的区别)
15     //参数二:系统保留字段
16     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
17     //第二种方式:自己创建的
18     //参数一:表示你这个队列的一个名字
19     //参数二:系统提供的宏
20     dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
21     //有队列的,是根据队列去创建子线程,是没有固定顺序的,随机执行,下面创建5个子线程添加到并行队列中,运行可以看出,执行是没有固定顺序的.
22     dispatch_async(queue, ^{
23         NSLog(@"111%@, 111%@", [NSThread currentThread], [NSThread mainThread]);
24     });
25
26     dispatch_async(queue, ^{
27         NSLog(@"222%@, 222%@", [NSThread currentThread], [NSThread mainThread]);
28     });
29
30     dispatch_async(queue, ^{
31         NSLog(@"333%@, 333%@", [NSThread currentThread], [NSThread mainThread]);
32     });
33
34     dispatch_async(queue, ^{
35         NSLog(@"444%@, 444%@", [NSThread currentThread], [NSThread mainThread]);
36     });
37
38     dispatch_async(queue, ^{
39         NSLog(@"555%@, 555%@", [NSThread currentThread], [NSThread mainThread]);
40     });
41
42 #pragma mark - 几秒之后去做每一件事
43     //延时队列
44     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
45         NSLog(@"3.0秒之后");
46     });
47
48 #pragma mark - 重复往一个队列中添加多个任务
49     //还是创建一个并行队列(CONCURRENT:并行,与最上面介绍的串行相对应)
50     dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
51     //添加多个任务
52     //参数一:任务的数量(重复执行100次)
53     //参数二:队列名,可以随便起个名,这里我就起名index
54     dispatch_apply(100, queue, ^(size_t index) {
55         NSLog(@"%ld", index);
56     });
57
58 #pragma mark - 分组group
59     //创建一个分组(为了是安插监听函数)
60     dispatch_group_t group = dispatch_group_create();
61     //创建一个并行队列
62     dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
63     //创建任务一
64     dispatch_group_async(group, queue, ^{
65         NSLog(@"我是任务一");
66     });
67     dispatch_group_async(group, queue, ^{
68         NSLog(@"我是任务二");
69     });
70
71     //任务监管的函数,监听所有执行任务的执行情况的,必须放在所有任务的最下方
72     dispatch_group_notify(group, queue, ^{
73         NSLog(@"我是监考官");
74     });

GCD串行,并行

时间: 2024-10-24 18:06:48

多线程简介及GCD的使用的相关文章

多线程编程4 - GCD

一.简介 在iOS所有实现多线程的方案中,GCD应该是最有魅力的,因为GCD本身是苹果公司为多核的并行运算提出的解决方案.GCD在工作时会自动利用更多的处理器核心,以充分利用更强大的机器.GCD是Grand Central Dispatch的简称,它是基于C语言的.如果使用GCD,完全由系统管理线程,我们不需要编写线程代码.只需定义想要执行的任务,然后添加到适当的调度队列(dispatch queue).GCD会负责创建线程和调度你的任务,系统直接提供线程管理 二.调度队列(dispath qu

iOS 多线程:『GCD』详尽总结

本文用来介绍 iOS 多线程中 GCD 的相关知识以及使用方法.这大概是史上最详细.清晰的关于 GCD 的详细讲解+总结的文章了.通过本文,您将了解到: 1. GCD 简介 2. GCD 任务和队列 3. GCD 的使用步骤 4. GCD 的基本使用(6种不同组合区别) 5. GCD 线程间的通信 6. GCD 的其他方法(栅栏方法:dispatch_barrier_async.延时执行方法:dispatch_after.一次性代码(只执行一次):dispatch_once.快速迭代方法:dis

多线程——NSThread、GCD、NSOperation

1.前言: 一个应用程序就是一个进程,一个进程至少包含一个线程,程序启动会自动创建一个主线程,负责UI界面的现实和控件事件的监控.多线程可以更充分的利用系统CPU资源,一定程度上提升程序的性能.1个进程可以开启多条线程,每条线程可以并行(同时)执行不同的任务.在一个线程内可以包含多个事物(要干的活),在线程内依据先进先出的特性串行执行…… 2.NSThread - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"main thread is %@

iOS多线程开发之GCD(下篇)

上篇和中篇讲解了什么是GCD,如何使用GCD,这篇文章将讲解使用GCD中将遇到的死锁问题.有兴趣的朋友可以回顾<iOS多线程开发之GCD(上篇)>和<iOS多线程开发之GCD(中篇)>. 言归正传,我们首先来回顾下死锁,所谓死锁: 是指两个或两个以上的进程(线程)在执行过程中,因争夺资源(如数据源,内存等,变量不是资源)而造成的一种互相等待的现象,若无外部处理作用,它们都将无限等待下去. 死锁形成的原因: 系统资源不足 进程(线程)推进的顺序不恰当: 资源分配不当 死锁形成的条件:

iOS开发多线程篇—多线程简介

iOS开发多线程篇-多线程简介 一.进程和线程 1.什么是进程 进程是指在系统中正在执行的一个应用程序 每一个进程之间是独立的.每一个进程均执行在其专用且受保护的内存空间内 比方同一时候打开QQ.Xcode,系统就会分别启动2个进程 通过"活动监视器"能够查看Mac系统中所开启的进程 2.什么是线程 1个进程要想运行任务,必须得有线程(每1个进程至少要有1条线程) 线程是进程的基本运行单元,一个进程(程序)的全部任务都在线程中运行 比方使用酷狗播放音乐.使用迅雷下载电影,都须要在线程中

iOS开发多线程网络———多线程概念及GCD

@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(htt

多线程开发之三 GCD

NSThread.NSOperation.GCD 总结: 无论使用哪种方法进行多线程开发,每个线程启动后并不一定立即执行相应的操作,具体什么时候由系统调度(CPU 空闲时就会执行) 更新 UI 应该在主线程(UI 线程)中进行,并且推荐使用同步调用,常用的方法如下: - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait; - (void)performSelec

学习IOS开发网络多线程篇--NSThread/GCD/

NSThread:利用NSThread创建和启用一个线程 1. NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];,调用后调用[thread start]; 2. 创建线程后自动启动线程 ,[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil]; 3. 隐式创建

嵌入式 Linux进程间通信(十一)——多线程简介

嵌入式 Linux进程间通信(十一)--多线程简介 一.线程简介 线程有四种:内核线程.轻量级进程.用户线程.加强版用户线程 1.内核线程 内核线程就是内核的分身,一个分身可以处理一件特定事情.内核线程的使用是廉价的,唯一使用的资源就是内核栈和上下文切换时保存寄存器的空间.支持多线程的内核叫做多线程内核(Multi-Threads kernel ). 2.轻量级进程LWP 轻量级进程(LWP)是一种由内核支持的用户线程,是基于内核线程的高级抽象,只有先支持内核线程,才能有轻量级进程LWP.每一个