首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在main中创建的同步调用串行队列是正常的,而在main中的同步调用主队列是死锁

首先,需要了解什么是调用队列。调用队列是一种用于管理任务执行顺序的机制,它按照特定的规则将任务按顺序排列并逐个执行。在多线程编程中,调用队列常用于控制并发执行的任务。

在这个问题中,我们提到了两种调用队列:同步调用串行队列和同步调用主队列。

  1. 同步调用串行队列: 同步调用串行队列是指任务按照顺序逐个执行,并且每个任务的执行都会等待上一个任务完成后才开始。这种队列保证了任务的顺序性,但是会阻塞当前线程,直到所有任务执行完毕。
  2. 同步调用主队列: 同步调用主队列是指将任务添加到主队列中,并且在当前线程中同步执行。主队列是一个特殊的调用队列,它是在应用程序的主线程上执行任务的。同步调用主队列会导致死锁,因为主队列中的任务需要在主线程上执行,而当前线程又在等待主队列中的任务执行完毕,从而形成了循环等待的情况。

解决这个问题的方法是将同步调用主队列改为异步调用主队列。异步调用主队列不会阻塞当前线程,而是将任务添加到主队列中等待主线程空闲时执行。这样可以避免死锁的发生。

总结:

  • 同步调用串行队列是正常的,任务按顺序逐个执行。
  • 同步调用主队列会导致死锁,因为主队列中的任务需要在主线程上执行,而当前线程又在等待主队列中的任务执行完毕。
  • 解决方法是将同步调用主队列改为异步调用主队列,避免死锁的发生。

腾讯云相关产品和产品介绍链接地址:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

GCD概念和基本使用GCD概念和基本使用

苹果公司为多核并行运算提出解决方案; GCD 会自动利用更多CPU内核(比如双核、四核) GCD 会自动管理线程生命周期(创建线程、调度任务、销毁线程) 总结:将任务添加到队列,并且指定执行任务函数...()获取; 专⻔用来主线程上调度任务串行队列; 全局并发队列 为了方便程序员使用,苹果提供了全局队列dispatch_get_global_queue(0, 0) 全局队列并发队列,包含四个优先级...2、GCD使用 2.1 创建 同步函数 dispatch_sync(dispatch_get_main_queue();, ^{ }); 异步函数 dispatch_async(dispatch_get_main_queue...这种情况下也会产生死锁,任务二(同步函数)和任务三(同步函数需要执行block)相互等待; 总体来说涉及到串行队列嵌套就容易出现死锁,使用时一定要注意;串行队列里添加同步任务队列必定会出现死锁; 2.3...所有的异步函数都添加到队列,然后再纳入队列监听范围。 使用dispatch_group_notify函数,来监听上面的任务是否完成,如果完成, 就会调用这个方法。

1K20

GCD 概念解释方法:

执行任务函数:GCD,任务通过 block来封装,并且任务block没有参数也没有返回值。...GCD使用步骤: 第一步: 创建/获取 队列 第二步: 创建任务,确定要做事情 第三步: 将任务添加到队列 (1)GCD会自动将队列任务取出,放到对应线程执行 (2)任务取出遵循队列...主队列: 遇到主队列,不管同步异步都要先执行完主线程里代码再执行主队列代码 dispatch_sync方法不能在主队列调用,因为这会无限期阻止线程并会导致你应用死锁。...只有当主线程空闲时, 主队列才会调度任务到主线程执行 主队列系统提供,无需自己创建,可以直接通过dispatch_get_main_queue()函数来获取。...,同步执行(死锁)主线程和主队列同步任务相互等待,造成死锁

883130

iOS_多线程一:GCD+混搭测试

一般一个block或者函数。  •分发队列:GCD以队列方式进行工作,例如FIFO。  •GCD会根据分发队列类型,创建合适数量线程执行队列任务。...当你创建多个Serial queue时,虽然它们各自是同步执行,但Serial queue与Serial queue之间并发执行。...  同步-并发:主线程,顺序执行,阻塞 7、同步-串行 // 例:之前百度面试遇到题 NSLog(@"1"); dispatch_sync(dispatch_get_main_queue(),...^{ // 串行 同步队列 NSLog(@"2"); }); NSLog(@"3"); // 输出:1 // 3加入队列 2加入队列;FIFO:3等待2执行 而23后面 // 所以造成死锁...,并发执行,不阻塞 主线程,顺序执行,阻塞 串行 main_queue 主线程,顺序执行,不阻塞 死锁 !!!

43820

iOS GCD编程之dispatch

) 设置为nil时 为串行队列串行队列block按照先进先出(FIFO)顺序去执行,实际上为单线程执行 当队列为并行时,没有固定顺序,为多线程执行 队列执行 基本 dispatch_async...死锁例子 死锁例子1 如果queue1一个串行队列的话,这段代码立即产生死锁: dispatch_sync(queue1, ^{ dispatch_sync(queue1, ^{     //......... });   //......  }); 死锁例子2 主线程执行会死锁 dispatch_sync(dispatch_get_main_queue(), ^{   //.........  }); }); 多线程操作数据库 dispatch队列线程安全,可以利用串行队列实现锁功能。...对象需要使用任何事件或者计时器都可以从该对象队列中指向,使得这些句柄可以自动队列上执行,从而使得句柄可以与对象自动同步

1.2K10

iOS多线程之三:GCD使用

但是,也正因为这样同步特性,实际项目中,当有同步任务添加到正在执行同步任务队列时,串行队列会出现死锁。而且由于同步任务会阻塞主线程运行,可能会导致某个事件无法响应。...Paste_Image.png 从以上代码可以看出,与串行不同,不需要等到A任务调用完,就已经调用B、C,显著地提高了线程执行速度,凸显了并行队列所执行异步操作并行特性; 另外,从这段代码...,不同串行队列需要创建一个新队列,而并行队列,只需要调用iOS系统为我们提供全局共享dispatch_get_global_queue就可以了: dispatch_queue_t queue...Paste_Image.png 从上面代码可以看出 第一个参数predicate,该参数检查后面第二个参数所代表代码块是否被调用谓词, 第二个参数则是整个应用程序只会被调用一次代码块。...所以如果循环代码需要一定时间执行,可以考虑另一个线程调用这两个函数。如果你传递参数串行queue,而且正是执行当前代码queue,就会产生死锁

3K20

OC底层探索22-GCD(上)OC底层探索22-GCD(上)define DISPATCH_QUEUE_WIDTH_FULL 0x1000ulldefine DISPATCH_QUEU

可以看到GCD属于libDispatch这个库; libDispatch源码下载 2、mainQueue 主队列 // 重点注释翻译: // 主队列用来应用程序上下文中进行交互主线程和runloop...dq_atomic_flags=1代表串行队列; 2.1 mianQueue创建 - libdispatch_init 通过注释翻译我们知道,mian_queuemain函数之前就已经被系统调用了;...一路查找下来才发现block调用位置,也是自动释放池里使用函数调用方式; 最后调用_dispatch_call_block_and_release完成了释放; 6、dispatch_sync同步函数...,其实同步函数串行队列就是通过栅栏函数来实现了,这部分也会在下一篇中分析; 这个位置出现死锁情况会在下篇文章中分析; 6.1 串行队列情况 忽略一些无关代码之后调用栈: _dispatch_barrier_sync_f...当然即使不太了解内核也不影响我们对GCD底层基本了解和分析,本文对GCD串/并队列创建同步、异步函数执行分析完了。 欢迎留言和我沟通!

53010

iOS多线程——你要知道GCD都在这里你要知道iOS多线程NSThread、GCD、NSOperation、RunLoop都在这里

异步执行栗子实验完了,可以发现,异步执行仅仅不会阻塞当前线程,但是否并发执行需要依靠传入队列,如果传递串行队列就是串行执行,传入并发队列就是并发执行,接下来看一下同步执行实验。...- (void)viewWillAppear:(BOOL)animated { /* 创建一个串行队列 这里不可以使用主队列了,因为执行该方法主线程,如果使用同步执行提交到主队列会造成死锁...,异步提交不会造成线程阻塞,所以三个任务都被提交到了串行队列,但是由于线程执行按顺序,所以三个任务按次序依次执行。...NSLog(@"After"); } 上述代码就会产生死锁,分析下原因,首先,viewWillAppear:方法主线程执行,接着调用dispatch_sync方法,该方法会阻塞当前线程,也就是会阻塞主线程...可以看出死锁产生条件一般都发生在同步执行方法,所以,使用同步执行方法时要避免任务再次派发到同一个线程

2K100

阿里、字节:一套高效iOS面试题( 多线程 GCD底层原理篇)

完了,然后系统就会根据任务类型和队列来执行任务(到底同步执行,还是异步执行,在那个队列执行)。 2.1 创建队列队列Main Dispatch Queue) 主队列,一个特殊 串行队列。...主队列串行队列,且只能选择异步执行,毕竟 同步执行 + 主队列 = 死锁 。...拜谢 至于 队列嵌套队列 ,这里也给一个表格(【】代表外层操作,并且所有外层操作都能正常运行前提下): 【同步执行 + 串行队列】嵌套同一个串行队列同步执行 + 并行队列】嵌套同一个并行队列...dispatch_apply 队列表现(当前为主线程): 主队列死锁(毕竟这是同步执行); 串行队列串行队列会完全抵消 dispatch_apply 并行迭代功能,还不如 for 循环;...重写该方法时,不要调用 [super main]。同时,main 方法将自动一个自动释放池中执行,无所另外创建自动释放池。

4.4K50

iOS学习——(转)多线程

异步多线程代名词 队列:装载线程任务队形结构。(系统以先进先出方式调度队列任务执行)。GCD中有两种队列串行队列和并发队列。 并发队列:线程可以同时一起进行执行。...= main} 串行同步3 {number = 1, name = main} 串行同步3 {number = 1, name = main} 串行异步:开启新线程,但因为任务串行,所以还是按顺序执行任务...主队列同步造成死锁原因: 如果在主线程运用主队列同步,也就是把任务放到了主线程队列。 而同步对于任务立刻执行,那么当把第一个任务放进主队列时,它就会立马执行。...block任务主线程执行,而运用addExecutionBlock加入任务子线程执行。...其他队列包含了串行和并发。 主队列创建如下,主队列任务主线程执行

1.2K20

iOS - 多线程(三):GCD

队列(dispatch_queue_main_t) 主队列一种特殊串行队列,它特殊与主线程关联,主队列任务都在主线程上执行,主队列程序一开始就被系统创建并与主线程关联。...全局并发队列与手动创建并发队列区别: 手动创建并发队列可以设置唯一标识,可以跟踪错误,而全局并发队列没有; ARC 不需要考虑释放内存,dispatch_release(q);不需要也不允许调用...而在 MRC 由于手动创建并发队列 create 出来,所以需要调用dispatch_release(q);来释放内存,而全局并发队列不需要; 全局并发队列可以指定服务质量(服务质量有助于确定队列执行任务优先级...1.5.2 GCD 死锁 死锁情况: 使用dispatch_sync函数往当前串行队列添加任务,会卡住当前串行队列(产生死锁)。 死锁原因: 队列引起循环等待。...当我们想让不同队列任务同步执行时,我们可以创建一个串行队列,然后将这些队列 target 指向新创建队列即可,比如: ?

2.4K31

《java并发编程实战》总结

程序应尽量使用开放调用。与那些持有锁时候调用外部方法程序相比,更容易对依赖开放调用程序进行死锁分析。...14.2 使用条件队列 14.2.1 条件谓语 条件谓语使某个操作称为状态依赖操作前提条件。阻塞队列,只有当队列不为空 时,take方法才能执行,否则必须等待。...调用wait之前测试条件谓词,并且从wait返回时再次进行测试。 一个循环中调用wait。 确保使用与条件队列相关锁来保护构成条件谓词各个状态变量。...15.2 硬件对并发支持 CAS主要缺点:使调用者处理竞争问题(通过重试、回退、放弃),而在能自动处理竞争问题(线程获得锁之前一直阻塞)。...Java内存模型规定了所有的变量都存储内存,每条线程还有自己工作内存,线程工作内存中保存了该线程用到变量内存副本拷贝,线程对变量所有操作都必须在工作内存中进行,而不能直接读写内存

18010

iOS 面试策略之系统框架-并发编程

串行队列(Serial Queue)指队列同一时间只能执行一个任务,当前任务执行完后才能执行下一个任务,串行队列只有一个线程。...异步(Async)也会把当前任务加入到队列,但它会立刻返回,无需等任务执行完成,也就是说异步不会阻塞线程。 无论串行还是并发队列都可以执行执行同步或异步操作。...注意在串行队列上执行同步操作容易造成死锁并发队列上则不用担心。异步操作无论实在串行队列还是并发队列上都可能出现竞态条件问题;同时异步操作经常与逃逸闭包一起出现在 API 设计当中。...接着,对同一个串行队列中进行异步、同步嵌套。这里会构成死锁,所以只会打印出 125 或者 152。 最后,串行队列中进行同步、异步嵌套,不会构成死锁。...第 1 种串行队列,无论读写,同一时间只能做一个操作,这样就保证了队列安全。其缺点速度慢,尤其大量读写发生时,每次只能做单个读或写操作效率实在太低。

84040

多线程(二):GCD

1、添加任务到队列同步、异步): dispatch_sync: 同步添加,将指定任务block同步追加到queue追加block结束之前,dispatch_sync会一直等待; 如果在主线程上执行同步任务...(任务也主线程执行),会造成死锁: //会造成死锁 dispatch_sync(dispatch_get_main_queue(), ^{ // }); 但是异步任务里可以用来切换到主线程 dispatch_async...系统默认有一个串行队列:主队列main_queue)和并行队列:全局队列(global_queue),不需要自己手动释放,或者自己创建用户队列(需要手动释放)。...串行队列,无区别,但是并行队列,用这个函数添加任务可以保证阻碍线程执行,即这个任务串行执行。可用于解决数据竞争问题。...有个坑要注意,并行队列必必须自己dispatch_queue_create创建,不能用dispatch_get_global_queue 实现原理:queue其他block已经开始各自分配线程执行

40420

iOS多线程之GCD、OperationQueue 对比和实践记录

区别 GCD: 将任务(block)添加到队列(串行/并发/主队列),并且指定任务执行函数(同步/异步) GCD底层C语言构成API iOS 4.0 推出,针对多核处理器并发技术 队列执行由...比如下面代码示例for循环内部创建时,每个循环都是创建一个新串行队列,里面只装一个任务,多个串行队列,结果整体上并发效果。想要串行效果,必须在for循环外部创建串行队列。...注意:替换后, dispatch_apply 函数整体上同步执行,内部 block 执行类型(串行/并发)由队列类型决定,但是串行队列死锁,建议用并发队列。...比如:主线程上同步执行任务时,因任务和之前已加入主队列但未执行任务会相互等待,导致死锁。 func testDeadLock(){ //主队列同步执行,会导致死锁。...,故串行队列同步执行任务不一定死锁

1.5K40

GCD API 理解 (一)资料先行

iOS 串行队列有两种:主队列(dispatch_get_main_queue())、通过dispatch_queue_create创建串行队列 1.1创建串行队列队列系统为我们应用创建...同步 异步 串行队列创建新线程,顺序执行 创建新线程,顺序执行 并发队列创建新线程,顺序执行 创建新线程,随机执行(不知哪个任务先执行完) 串行队列无论同步执行任务,还是异步执行任务,任务都是顺序执行...** 情形一** 主线程调度主队列完成一个同步任务,会发生死锁。...而dispatch_sync又会等viewDidLoad执行完毕,再开始执行,因此就互相等待发生死锁。 ** 情形二 ** 串行队列同步任务再执行同步任务,会发生死锁。...** 情形三 ** 串行队列异步任务再嵌套执行同步任务,也会发生死锁

45621

iOS——GCD死锁案例

串行与并行 使用GCD时候,我们会把需要处理任务放到Block,然后将任务追加到相应队列里面,这个队列,叫做Dispatch Queue。...举一个简单例子,在三个任务输出1、2、3,串行队列输出有序1、2、3,但是并行队列先后顺序就不一定了。 同步与异步 串行与并行针对队列,而同步与异步,针对则是线程。...分析: 这个案例没有使用系统提供串行或并行队列,而是自己通过dispatch_queue_create函数创建了一个DISPATCH_QUEUE_SERIAL串行队列。...因为异步线程,所以主线程任务5不必等待异步线程所有任务完成; 因为任务5不必等待,所以2和5输出顺序不能确定; 任务2执行完以后,遇到同步线程,这时,将任务3加入串行队列; 又因为任务4比任务...1、异步线程、任务5】加入Main Queue,异步线程任务:【任务2、同步线程、任务4】。

2K30

iOS-多线程详解

线程串行 1个线程任务执行串行 如果要在1个线程执行多个任务,那么只能一个一个地按顺序执行这些任务 也就是说,同一时间内,1个线程只能执行1个任务 5....dispatch_queue_t queue = dispatch_get_main_queue(); 任务执行 队列queue,任务block块 开启同步函数 同步函数:要求立刻马上开始执行...:不会开线程,任务串行执行 使用主队列(跟主线程相关联队列) 主队列GCD自带一种特殊串行队列,放在主队列任务,都会放到主线程执行 //1.获得主队列 dispatch_queue_t...因为这个方法主线程,给主线程添加任务,而同步函数要求立刻马上执行,因此就会相互等待而发生死锁。...非主队列同时具备了并发和串行功能,通过设置最大并发数属性来控制任务并发执行还是串行执行 NSOperationQueue作用 NSOperation可以调用start方法来执行任务,但默认同步执行

1.9K90

Apple 官方指南 - Dispatch Queues

分派队列Main dispatch queue) 分派队列一个全局串行分派队列,它在应用程序主线程执行任务。...因为主队列在你应用程序主线程执行任务,所以它常常被用作一个应用程序关键同步点。尽管你不需要创建一个分派队列,然而你需要确保你应用程序合理地声明了(drains)它。...而且,除非你异步地向一个串行队列提交你任务,串行队列就绝不会发生死锁。 并发队列被系统创建好供你使用,而串行队列则需要你自己去显式地创建和管理。...所以当你需要在已经队列上下文中执行代码里调用这两个函数时候需要非常小心。如果你将正在执行当前代码队列作为参数传入这两个函数而且这个队列又是串行队列的话,那该调用将造成队列死锁。...如果你不是创建一个 Cocoa 应用程序而且你也不想显式地创建一个运行循环,你就必须要调用 dispatch_main 函数来显式声明主分派队列

23320

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

4.5 同步执行 + 主队列 同步执行 + 主队列不同线程调用结果也是不一样,主线程调用会出现死锁而在其他线程则不会。...4.5.1 主线程调用同步执行 + 主队列 互相等待卡住不可行 /** * 同步执行 + 主队列 * 特点(主线程调用):互等卡不执行。...要是如果不在主线程调用而在其他线程调用会如何呢?...dispatch_apply按照指定次数将指定任务追加到指定队列,并等待全部队列执行结束。 如果串行队列中使用 dispatch_apply,那么就和 for 循环一样,按顺序同步执行。...还有一点,无论串行队列,还是异步队列,dispatch_apply 都会等待全部任务执行完毕,这点就像是同步操作,也像是队列dispatch_group_wait方法。

59970
领券