大家的知道在主队列上使用dispatch_sync(),

  1. - (void)testSyncMainThread {
  2.  
  3. dispatch_queue_t main = dispatch_get_main_queue();
  4. NSLog(@"*********1");
  5. dispatch_sync(main, ^(){
  6. NSLog(@"*********2");
  7. });
  8. NSLog(@"*********3");
  9. }

会造成线程阻塞,但是查找网上说的原因,发现基本上说法都是一样的,感觉不是不太好理解,

我查看一下API,

/*!

* @function dispatch_sync

*

* @abstract

* Submits a block for synchronous execution on a dispatch queue.

*

* @discussion

* Submits a workitem to a dispatch queue like dispatch_async(), however

* dispatch_sync() will not return until the workitem has finished.

*

* Work items submitted to a queue with dispatch_sync() do not observe certain

* queue attributes of that queue when invoked (such as autorelease frequency

* and QOS class).

*

* Calls to dispatch_sync() targeting the current queue will result

* in dead-lock. Use of dispatch_sync() is also subject to the same

* multi-party dead-lock problems that may result from the use of a mutex.

* Use of dispatch_async() is preferred.

*

* Unlike dispatch_async(), no retain is performed on the target queue. Because

* calls to this function are synchronous, the dispatch_sync() "borrows" the

* reference of the caller.

*

* As an optimization, dispatch_sync() invokes the workitem on the thread which

* submitted the workitem, except when the passed queue is the main queue or

* a queue targetting it (See dispatch_queue_main_t,

* dispatch_set_target_queue()).

*

* @param queue

* The target dispatch queue to which the block is submitted.

* The result of passing NULL in this parameter is undefined.

*

* @param block

* The block to be invoked on the target dispatch queue.

* The result of passing NULL in this parameter is undefined.

*/

结合API,我的理解:

第一步:当代码执行到 dispatch_sync()时,会首先把dispatch_sync()函数放到当前线程的队列(就是主队列中),而且这个线程并不会立即返回,而是会等待block中的任务都完成时才会返回,

第二步:再把block中的任务依次放到主队列中等待执行,

由于是同步执行,而且block中的任务在主队列的线性表中的前面有个dispatch_sync()等待完成,而dispatch_sync()的完成又依赖于block的执行完成,就这样造成了死锁。

最后:在其他队列上模拟这种死锁情况

  1. dispatch_queue_t lwMainQueue = dispatch_queue_create("lw.queue", DISPATCH_QUEUE_SERIAL);
  2. dispatch_sync(lwMainQueue, ^{
  3. NSLog(@"*********1");
  4. dispatch_sync(lwMainQueue, ^{NSLog(@"*********2");
  5. });
  6. NSLog(@"*********3");
  7. });

效果是一样的

iOS Dispatch_sync 阻塞线程的原因的更多相关文章

  1. 使用runloop阻塞线程的正确写法

    使用runloop阻塞线程的正确写法 runloop可以阻塞线程,等待其他线程执行后再执行. 比如: @implementation ViewController{    BOOL end;}…– ( ...

  2. iOS 多线程之线程锁Swift-Demo示例总结

    线程锁是什么 在前面的文章中总结过多线程,总结了多线程之后,线程锁也是必须要好好总结的东西,这篇文章构思的时候可能写的东西得许多,只能挤时间一点点的慢慢的总结了,知道了线程之后要了解线程锁就得先了解一 ...

  3. tornado 异步调用系统命令和非阻塞线程池

    项目中异步调用 ping 和 nmap 实现对目标 ip 和所在网关的探测 Subprocess.STREAM 不用担心进程返回数据过大造成的死锁, Subprocess.PIPE 会有这个问题. i ...

  4. fir.im Log Guru 正式开源,快速找到 iOS 应用无法安装的原因

    很开心的宣布 Log Guru 正式开源! Log Guru,是 fir.im 开发团队创造的小轮子,用在 Mac 电脑上的日志获取,Github 地址:FIRHQ/LogGuru. Log Guru ...

  5. iOS中的线程安全问题

    为了保证线程安全,不会因为多个线程访问造成资源抢夺,出现的运行结果的偏差问题,我们需要使用到线程同步技术,最常用的就是 @synchronized互斥锁(同步锁).NSLock.dispatch_se ...

  6. Delphi Socket 阻塞线程下为什么不触发OnRead和OnWrite事件

    //**********************************************************************************//说明: 阻塞线程下为什么不触 ...

  7. delphi TServerSocket阻塞线程单元 实例

    TServerSocket阻塞线程单元,希望对你有所帮助.需要注意的是:1.如果你使用TServerSocket的stNonBlocking模式,重写TServerClientThread线程时要重载 ...

  8. iOS中保证线程安全的几种方式与性能对比

    来源:景铭巴巴 链接:http://www.jianshu.com/p/938d68ed832c 一.前言 前段时间看了几个开源项目,发现他们保持线程同步的方式各不相同,有@synchronized. ...

  9. IOS 多线程,线程同步的三种方式

    本文主要是讲述 IOS 多线程,线程同步的三种方式,更多IOS技术知识,请登陆疯狂软件教育官网. 一般情况下我们使用线程,在多个线程共同访问同一块资源.为保护线程资源的安全和线程访问的正确性. 在IO ...

随机推荐

  1. 基于php双引号中访问数组元素

    关于 php访问数组 {} []

  2. poj 1741 Tree(树的点分治)

    poj 1741 Tree(树的点分治) 给出一个n个结点的树和一个整数k,问有多少个距离不超过k的点对. 首先对于一个树中的点对,要么经过根结点,要么不经过.所以我们可以把经过根节点的符合点对统计出 ...

  3. bzoj4435: [Cerc2015]Juice Junctions(最小割树+hash)

    传送门 首先最大流等于最小割,那么可以转化为最小割树来做(不知道什么是最小割树的可以看看这题->这里) 具体的做法似乎是$hash[i][j]$表示最小割为$i$时点$j$是否与$S$连通 然后 ...

  4. JMeter - 后处理器/脚本语言 - 比较

    当我们使用JMeter / Response数据处理进行密集负载测试时,我们可能会非常小心我们选择的后处理器/脚本语言的类型.在这篇文章中,我想说明这些后处理器/脚本语言如何影响测试的整体性能. 我们 ...

  5. Luogu P2624 [HNOI2008]明明的烦恼 Prufer+组合+高精

    好的我把标准版过了... 设$ r_i$为$i$的度数 首先,我们设 $ sum = \Sigma r_i-1$,$ tot $ 为所有能够确定度数的点 所以我们有 $ C ^ {sum} _{n-2 ...

  6. HDU-2588-GCD (欧拉函数)

    The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the ...

  7. Java定时任务的几种实现方式

    java Timer比较具体的实现实例 https://www.cnblogs.com/0201zcr/p/4703061.html 转载大神 的 https://blog.csdn.net/kegu ...

  8. 转 rman-08120 以及查询隐含参数

    rman-08120 We need RMAN to automatically purge archivelogs from the FRA once they are applied to the ...

  9. QT源码解析笔记

    1. QT如何绘制控件的 QT的绘制控件在QStyleSheetStyle::DrawControl里面,这里会调用默认的QSS来绘制效果 2. 在设置一次QSS以后,将会触发polish事件,里面将 ...

  10. RabbitMQ使用教程(三)如何保证消息99.99%被发送成功?

    1. 前情回顾 RabbitMQ使用教程(一)RabbitMQ环境安装配置及Hello World示例 RabbitMQ使用教程(二)RabbitMQ用户管理,角色管理及权限设置 在以上两篇博客发布后 ...