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 ...
随机推荐
- 基于 bootstrap 字体图标,用纯CSS实现星级评分功能
需要用到的图标 实现原理 关键属性是 text-overflow: clip;,表示直接截断文本.我们经常用这个属性的另一个值 text-overflow: ellipsis; 来做省略表示. 先平铺 ...
- Docker 容器的数据卷
数据卷的特点: 1. 数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会拷贝到新初始化的数据卷中 2. 数据卷可以在容器之间共享和重用 3. 可以对数据卷里的内容直接进行修改 ...
- [Xcode 实际操作]四、常用控件-(5)UILabel文本标签自定义文字样式
目录:[Swift]Xcode实际操作 本文将演示给标签对象添加描边效果,在项目文件夹上,点击鼠标右键菜单, 选择[Create File]->[Cocoa Touch Class]->[ ...
- 谈谈Vue/React中的虚拟DOM(vDOM)与Key值
谈谈Vue/React中的虚拟DOM(vDOM)与Key值 一.DocumentFragment 在了解虚拟DOM前,先来了解DOM的一个对象属性--DocumentFragment. 在一次操作中, ...
- 记一次工作中的小BUG
今天在调试代码的时候总是遇到一个bug,百思不得其解!先上bug图 我用的webapi 集成的swagger,错误提示是路由名称冲突,可我仔细检查了下并没有冲突的路由地址啊!于是上网查找资料,有位网友 ...
- SSM+Druid的搭建
SSM+druid开发配置 工程目录 1.先从pom文件开始吧 <project xmlns="http://maven.apache.org/POM/4.0.0" xmln ...
- 《SQL 进阶教程》 case:练习题1-1-3 用 ORDER BY 指定顺序进行排序
select name from greatestsORDER BY case when name ='B' then 1 when name ='A' then 2 when name ='D' t ...
- linux环境下jdk部署配置
1.java官网下载相关的jdk包 2.配置系统环境变量,编辑/etc/profile文件,在文件的末尾添加一下信息: export JAVA_HOME=/usr/jdk1.8.0_101export ...
- ip route,ip rule, iptables和docker的端口映射
iptables 默认5个表, 不可增加其他表 raw 用于配置数据包,raw 中的数据包不会被系统跟踪. filter 是用于存放所有与防火墙相关操作的默认表. nat 用于 网络地址转换(例如:端 ...
- VMware下linux与window文件夹共享
这里说的是在虚拟机下来实现在windows下共享一个文件夹. 下面来说明一下是如何实现的: 1. 安装VMware.Workstation. 2. 安装Redhat Linux 9.0,在虚拟机下 ...