iOS Dispatch_sync 阻塞线程的原因
大家的知道在主队列上使用dispatch_sync(),
- (void)testSyncMainThread { dispatch_queue_t main = dispatch_get_main_queue();
NSLog(@"*********1");
dispatch_sync(main, ^(){
NSLog(@"*********2");
});
NSLog(@"*********3");
}
会造成线程阻塞,但是查找网上说的原因,发现基本上说法都是一样的,感觉不是不太好理解,
我查看一下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的执行完成,就这样造成了死锁。
最后:在其他队列上模拟这种死锁情况
dispatch_queue_t lwMainQueue = dispatch_queue_create("lw.queue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(lwMainQueue, ^{
NSLog(@"*********1");
dispatch_sync(lwMainQueue, ^{NSLog(@"*********2");
});
NSLog(@"*********3");
});
效果是一样的
iOS Dispatch_sync 阻塞线程的原因的更多相关文章
- 使用runloop阻塞线程的正确写法
使用runloop阻塞线程的正确写法 runloop可以阻塞线程,等待其他线程执行后再执行. 比如: @implementation ViewController{ BOOL end;}…– ( ...
- iOS 多线程之线程锁Swift-Demo示例总结
线程锁是什么 在前面的文章中总结过多线程,总结了多线程之后,线程锁也是必须要好好总结的东西,这篇文章构思的时候可能写的东西得许多,只能挤时间一点点的慢慢的总结了,知道了线程之后要了解线程锁就得先了解一 ...
- tornado 异步调用系统命令和非阻塞线程池
项目中异步调用 ping 和 nmap 实现对目标 ip 和所在网关的探测 Subprocess.STREAM 不用担心进程返回数据过大造成的死锁, Subprocess.PIPE 会有这个问题. i ...
- fir.im Log Guru 正式开源,快速找到 iOS 应用无法安装的原因
很开心的宣布 Log Guru 正式开源! Log Guru,是 fir.im 开发团队创造的小轮子,用在 Mac 电脑上的日志获取,Github 地址:FIRHQ/LogGuru. Log Guru ...
- iOS中的线程安全问题
为了保证线程安全,不会因为多个线程访问造成资源抢夺,出现的运行结果的偏差问题,我们需要使用到线程同步技术,最常用的就是 @synchronized互斥锁(同步锁).NSLock.dispatch_se ...
- Delphi Socket 阻塞线程下为什么不触发OnRead和OnWrite事件
//**********************************************************************************//说明: 阻塞线程下为什么不触 ...
- delphi TServerSocket阻塞线程单元 实例
TServerSocket阻塞线程单元,希望对你有所帮助.需要注意的是:1.如果你使用TServerSocket的stNonBlocking模式,重写TServerClientThread线程时要重载 ...
- iOS中保证线程安全的几种方式与性能对比
来源:景铭巴巴 链接:http://www.jianshu.com/p/938d68ed832c 一.前言 前段时间看了几个开源项目,发现他们保持线程同步的方式各不相同,有@synchronized. ...
- IOS 多线程,线程同步的三种方式
本文主要是讲述 IOS 多线程,线程同步的三种方式,更多IOS技术知识,请登陆疯狂软件教育官网. 一般情况下我们使用线程,在多个线程共同访问同一块资源.为保护线程资源的安全和线程访问的正确性. 在IO ...
随机推荐
- Yaf + Smarty 整合笔记
Yaf真的是太简单了,简单到使用mvc的时候在view里面需要手写php脚本.因此考虑整合一下smarty模板引擎.随心所欲也正是yaf的魅力 Yaf 安装 这里简单说一下yaf的安装,已经是非常无脑 ...
- 【转】vs发布msi程序详解
源地址:http://wenku.baidu.com/link?url=MV1Mf7IukCZ0cab8AzXQoQ3MAXeUAHGz5b2IuUL4Kw-hCI90ZyBKXwKeQA3t3-SV ...
- 浮点数与快速log2
请先于浮点数的文章:http://blog.jobbole.com/86371/ 先贴一张关于float和double的图: float: double: 快速log2长这样: int flog2(f ...
- Node.js 内置模块crypto使用事件方法(onreadable)加密的一些问题
javaScript代码如下: 'use strict'; const crypto = require('crypto'); //实例化一个AES加密对象 const aesEncrept = cr ...
- PJzhang:英国通信总部GCHQ开源产品-网络瑞士军刀CyberChef
猫宁!!! 参考链接:https://www.4hou.com/info/news/981.html 这个产品免费开源易用,如果称之为网络瑞士军刀,没什么异议. github地址:https://gi ...
- 关于php命名空间的理解
以phpmailer这个类库为例,composer自动加载好该类库,有用的文件都放在src这个目录下 这些文件的命名空间都是这个:namespace PHPMailer\PHPMailer; 如果我们 ...
- Sequence( 分块+矩阵快速幂 )
题目链接 #include<bits/stdc++.h> using namespace std; #define e exp(1) #define pi acos(-1) #define ...
- python之Selenium库的使用
一 什么是Selenium selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并 ...
- Hadoop_配置Hadoop开发环境(Eclipse)
通常我们可以用Eclipse作为Hadoop程序的开发平台. 1) 下载Eclipse 下载地址:http://www.eclipse.org/downloads/ 根据操作系统类型,选择合适的版本 ...
- (转)linux 中特殊符号用法详解
linux 中特殊符号用法详解 原文:https://www.cnblogs.com/lidabo/p/4323979.html # 井号 (comments)#管理员 $普通用户 脚本中 #!/b ...