dispatch的几种队列

dispatch的几种队列

dispatch队列的生成可以有这几种方式:

1. dispatch_queue_t queue = dispatch_queue_create("com.dispatch.serial", DISPATCH_QUEUE_SERIAL); //生成一个串行队列,队列中的block按照先进先出(FIFO)的顺序去执行,实际上为单线程执行。第一个参数是队列的名称,在调试程序时会非常有用,所有尽量不要重名了。

2. dispatch_queue_t queue = dispatch_queue_create("com.dispatch.concurrent", DISPATCH_QUEUE_CONCURRENT); //生成一个并发执行队列,block被分发到多个线程去执行

3. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //获得程序进程缺省产生的并发队列,可设定优先级来选择高、中、低三个优先级队列。由于是系统默认生成的,所以无法调用dispatch_resume()和dispatch_suspend()来控制执行继续或中断。需要注意的是,三个队列不代表三个线程,可能会有更多的线程。并发队列可以根据实际情况来自动产生合理的线程数,也可理解为dispatch队列实现了一个线程池的管理,对于程序逻辑是透明的。

官网文档解释说共有三个并发队列,但实际还有一个更低优先级的队列,设置优先级为DISPATCH_QUEUE_PRIORITY_BACKGROUND。Xcode调试时可以观察到正在使用的各个dispatch队列。

4. dispatch_queue_t queue = dispatch_get_main_queue(); //获得主线程的dispatch队列,实际是一个串行队列。同样无法控制主线程dispatch队列的执行继续或中断。

Dispatch的死锁

接下来我们可以使用dispatch_async或dispatch_sync函数来加载需要运行的block。

dispatch_async(queue, ^{

  //block具体代码

}); //异步执行block,函数立即返回

dispatch_sync(queue, ^{

  //block具体代码

}); //同步执行block,函数不返回,一直等到block执行完毕。编译器会根据实际情况优化代码,所以有时候你会发现block其实还在当前线程上执行,并没用产生新线程。

实际编程经验告诉我们,尽可能避免使用dispatch_sync,嵌套使用时还容易引起程序死锁

如果queue1是一个串行队列的话,这段代码立即产生死锁:

dispatch_sync(queue1, ^{

dispatch_sync(queue1, ^{

    ......

  });

  ......

 });

循环等待造成的死锁。

在主线程上,执行下面代码也会造成死锁

dispatch_sync(dispatch_get_main_queue(), ^{

  ......

});

GDC给我们并行编程带来的极大的便捷之处,但是在使用的过程中,我们也要明白他们的工作的原理,避免出现一些问题

未来CTO
关注我CTO之路从此开始 微信号:wlaicto

时间: 2024-10-12 11:25:14

dispatch的几种队列的相关文章

【RabbitMQ】——5种队列(转)

原文地址:https://blog.csdn.net/u012654963/article/details/76417613 应用RabbitMQ,我们可以根据需求选择5种队列之一. 一.简单队列 P:消息的生产者 C:消息的消费者 红色:队列 简单队列的生产者和消费者关系一对一 但有时我们的需求,需要一个生产者,对应多个消费者,那就可以采用第二种模式 二.Work模式 一个生产者.2个消费者. 但MQ中一个消息只能被一个消费者获取.即消息要么被C1获取,要么被C2获取.这种模式适用于类似集群,

Java 几种队列区别的简单说明

前言 队列,字面意思就可以明白. 是一种线性的数据暂存与管理工具. 也可以让各种业务功能进行逐个的队列运行. 此篇博客只说明一下Java有几种队列 未阻塞和阻塞队列的区别 未阻塞: 1.未阻塞的队列在并发想队列添加或者取得数据的时候,必定只会有一个成功,其他都可能添加失败. 阻塞: 1.阻塞的队列会进行线程阻塞操作,让并发的添加或者取得数据进行一定程度的延迟,可以保证大量并发数据的添加. 但是阻塞也是有超时时间的.. 超过一段时间后依然会抛出异常或者抛出false 没有实现阻塞接口 实现java

QueueDemo+Deque 两种队列的演示

QueueDemo /** * 队列Queue 的演示 * 知识点: 队列是一种常用的数据机构, 遵循先进先出的原则 * 可以将队列看成特殊的线性表,队列限制了对线性表的访问方式: * 只能从线性表的一端添加(offer)元素,从另一端取出(poll)元素. * JDK中提供了Queue接口,同时使得LinkedList实现了该接口 * 原因: 选择LinkedList实现Queue,因为Queue经常要进行插入和删除的操作, * 而LinkedList在这方面效率较高. * 应用: 比如游戏列

ArrayBlcokingQueue,LinkedBlockingQueue与Disruptor三种队列对比与分析

一.基本介绍 ArrayBlcokingQueue,LinkedBlockingQueue是jdk中内置的阻塞队列,网上对它们的分析已经很多,主要有以下几点: 1.底层实现机制不同,ArrayBlcokingQueue是基于数组的,LinkedBlockingQueue是基于链表的: 2.初始化方式不同,ArrayBlcokingQueue是有界的,初始化时必须指定队列的大小:LinkedBlockingQueue可以是无界的,但如果初始化时指定了队列大小,也可以做为有界队列使用: 3.锁机制实

Python_内置四种队列

from queue import Queue #LILO队列q = Queue() #创建队列对象q.put(0) #在队列尾部插入元素q.put(1)q.put(2)print('LILO队列',q.queue) #查看队列中的所有元素print(q.get()) #返回并删除队列头部元素print(q.queue) from queue import LifoQueue #LIFO队列lifoQueue = LifoQueue()lifoQueue.put(1)lifoQueue.put(

两种队列

1.Stack和Queue Stack是先进后出的,Queue是先进先出的. 使用方法如下: public class Dog { public string Name { get; set; } public Dog(string name) { this.Name = name; } public void ConsoleName() { Console.WriteLine(this.Name); } } //栈 先进后出 Stack<Dog> s = new Stack<Dog&g

GCD(Grand Central Dispatch)的详解

GCD(Grand Central Dispatch) FIFO(先入先出) Dispatch(派遣,急件,分派) Serial (连续的,连载的,分期偿还的) Dispatch Queue(调度队列) Serial Dispatch Queue(串行调度队列) Concurrent Dispatch Queue(并发调度队列) Main Dispatch Queue(主要调度队列) Global Dispatch Queue(全局调度队列) dispatch_apply是(同步函数) GCD是

创建Dispatch Queue

第一.dispatch_queue_create 用于创建用户线程队列.可以创建Serial Dispatch Queue 和Concurrent Dispatch Queue两种队列,Serial Dispatch Queue是等待现在正在执行的Queue,即串行执行 Concurrent Dispatch Queue不等待现在正在执行中的Queue,即并行队列 1.创建Serial Dispatch Queue dispatch_queue_t serialQueue=dispatch_qu

IOS多线程_GCD的简单使用和详细说明

//你可以先看看这个例子的效果找点感觉,再看说明 @interface yxpGCDVController () { UIImageView *_imageView; } @end @implementation yxpGCDVController - (void)viewDidLoad { [super viewDidLoad]; self.title=@"GCD"; //初始化一_ImageView _imageView=[[UIImageView alloc] initWithF