深入理解Grand Central Dispatch (GCD)(一)
来源:互联网 发布:什么叫一级域名 编辑:程序博客网 时间:2024/05/06 04:01
多线程
首先,线程是什么?如果你有一些计算机的基础知识,这可能难不倒你。
应用程序启动后,首先便将包含在应用程序中的CPU命令列配置到内存中。CPU从应用程序指定的地址开始,一个一个地执行CPU命令列。
虽然Objectve-C中的if语句和for语句等控制流语句或者函数调用的情况下,执行命令列的地址会远离当前的位置。但是,由于一个CPU一次只能执行一个命令,不能同时执行两个命令,因此CPU执行的命令就像是一条无分叉的道路。
“一个CPU执行的命令为一条无分叉的路径”即为“线程”。
通过CPU分时,或者多核CPU可以实现多线程。
多线程看上去是好事,实际上,多线程编程极易发生各种问题,比如:
- 数据竞争
- 死锁
- 太多线程导致消耗大量内存
下文中会有对这三点的描述
Dispatch Queue
苹果官方对GCD有一段描述:
开发者要做的只是定义想执行的任务并追加到适当的Dispatch Queue中。
对这句话的理解应当聚焦在两个关键词上——“任务”和“Dispatch Queue”
Dispatch Queue即队列,它是任务的队列,上面按顺序排列着任务。所以,任务又是什么?任务可以看做是代码片段,一段代码,一个函数。我们用下面的方式把任务追加到Dispatch Queue上时,任务是Block。
dispatch_async(queue,^{/**想执行的任务*/});
串行队列和并发队列
Dispatch Queue有两种,分别是:Serial Dispatch Queue和Concurrent Dispatch Queue,即串行队列和并发队列。
串行队列中的每个任务是串行执行的,按照任务追加的顺序,等待一个任务执行完成后再执行下一个任务。
并发队列里的每个任务是并发执行的,不等待现在执行的任务结束就可以执行下一个任务。
假设向队列queue中依次追加8个任务blk0~blk7
dispatch_async(queue,blk0);dispatch_async(queue,blk1);dispatch_async(queue,blk2);dispatch_async(queue,blk3);dispatch_async(queue,blk4);dispatch_async(queue,blk5);dispatch_async(queue,blk6);dispatch_async(queue,blk7);
当变量queue为串行队列时,因为要等待现在执行中的任务结束,所以先执行blk0,等blk0执行完成后执行blk1,然后是blk,2,blk3,如此重复。即执行该源代码后,一定按照下面的顺序执行处理。 blk0->blk1->blk2->blk3->blk4->blk5->blk6->blk7
当queue为并发队列时,因为不用等待现在执行中的任务处理结束,所以先执行blk0,不管blk0的执行是否完成,都开始执行后面的blk1,不管blk1执行是否完成,都开始执行后面的blk2,如此重复循环。
Dispatch Queue(队列)与线程
虽然并发队列不用等待任务处理结束,可以并行执行对个任务,但是并行执行的任务数量取决于当前系统的状态。即基于Dispatch Queue中的处理数、CPU核数以及CPU负荷等当前系统的状态来决定并发队列中并行执行的任务数量。所谓”并行执行“就是使用多个线程同时执行多个处理。
上面的源码,假设系统准备了四个线程
任务的执行状况,可由上表表示
而一个串行队列只使用一个线程。
dispatch_queue_create
我们知道了有两种Dispatch Queue,那么怎么获得Dispatch Queue呢?有两种方法,第一种就是自己创建一个Dispatch Queue。
如果你想创建一个串行队列:
dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("mySerialQueue",NULL);
如果你想创建一个并发队列:
dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("myConcurrentlQueue",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_create函数的第一个参数是队列的名称,接受一个C语言字符串。第二个参数是队列的类型,如果串行队列就为NULL,并发队列指定为DISPATCH_QUEUE_CONCURRENT。
就像前面所说的,每一个串行队列使用一个线程,在使用dispatch_queue_create创建多个串行队列是,相当于创建了多个线程。由于创建过多的线程会消耗大量的内存,所以不要一激动就创建大量串行队列。创建串行队列必须有充足的理由。
Main Dispatch Queue/Global Dispatch Queue
第二种获取队列的方法就是获取系统标准提供的Dispatch Queue。
系统提供两个Dispatch Queue。Main Dispatch Queue和Global Dispatch Queue。
Main Dispatch Queue就是在主线程中执行的队列。是串行队列。
Global Dispatch Queue是一个并发队列。
Global Dispatch Queue有四个优先级,分别是高优先级,默认优先级,低优先级和后台优先级。四种优先级只是大致的优先程度区分。
获得各种系统提供Dispatch Queue的方法:
/**Main Dispatch Queue的获取方法*/dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();/**Global Dispatch Queue的获取方法*/dispatch queue_t globalDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)
可以改变dispatch_get_global_queue的第一个参数,获得不同优先级的Global Dispatch Queue。
- 深入理解Grand Central Dispatch (GCD)(一)
- Grand Central Dispatch(GCD)
- Grand Central Dispatch(GCD)
- GCD(Grand Central Dispatch)
- Grand Central Dispatch(GCD)
- GCD(Grand central dispatch)
- Grand Central Dispatch(GCD)
- Grand Central Dispatch (GCD) Reference (原创)Grand Central
- Grand Central Dispatch(GCD)编程基础
- IOS-Grand Central Dispatch(GCD)
- IOS多线程GCD(Grand central Dispatch)
- Grand Central Dispatch(GCD)编程基础
- Grand Central Dispatch(GCD)编程基础
- Grand Central Dispatch(GCD)编程基础
- Grand Central Dispatch(GCD)编程基础
- 多线程之GCD(Grand Central Dispatch)
- GCD索引(Grand Central Dispatch (GCD) Reference )
- Grand Central Dispatch (GCD)
- Pathon 复制一个集合
- 【c/c++】运算符优先级
- Java基础--IO流02(字符缓冲区、字节流、装饰设计模式)
- java.io.Serializable浅析
- 我的第一个定时任务
- 深入理解Grand Central Dispatch (GCD)(一)
- IDEA自定义格式化
- oracle 查询包含某字段的所有表
- 在安全层面,企业如何获得更好的投资回报率 ROI?
- 使用Firefox user agent进行移动端网页测试
- unterminated string literal
- iOS MagicRecord 详解
- android html超链接文本 点击跳转的两种实现
- IOS版添加phonegap-银联支付插件教程