回来又复习了一下自己之前的GCD的内容,发现还是不能好好理解同步和异步、串行和并发,还有一个并行的概念,整理了一下笔记,希望不要再被绕晕了😓。
先看看这几幅图




基于GCD来讲解一下,到底这些概念是干嘛的,参考于理解GCD死锁
dispatch_sync
是同步函数,不具备开启新线程的能力,交给它的block,只会在当前线程执行,不论你传入的是串行队列还是并发队列,并且,它一定会等待block被执行完毕才返回。
dispatch_async
是异步函数,具备开启新线程的能力,但是不一定会开启新线程,交给它的block,可能在任何线程执行,开发者无法控制,是GCD底层在控制。它会立即返回,不会等待block被执行
。
下面来看看困扰了我很久的主线程阻塞函数:
override func viewDidLoad() {
super.viewDidLoad()
print("Start \(NSThread.currentThread())")
//GCD同步函数
dispatch_sync(dispatch_get_main_queue(), {
for i in 0...100{
print("\(i) \(NSThread.currentThread())")
}
})
print("End \(NSThread.currentThread())")
}
Main Queue
等待dispatch_sync
的返回,dispatch_sync
等待block
的完成,而block
又在等待Main Queue
执行完成才会开始。
解决方案就可以从串行/并发
或者同步/异步
的思路去想了。
1.串行/并发
从这个角度出发的话,其实就是从对执行室的容量
的角度出发,并发相当于扩大了执行室的容量,使得队列得到疏通。
当然,不让Main Queue
等待也行,把queue
改成一个新建的queue
的话,其实这个环就可以得以解开了。即将block放入自己的串行队列,不再和viewDidLoad()处于一个队列,解决了队列阻塞,因此避免了死锁问题。
2.同步/异步
如果从这个角度出发,其实就是从要不要等待执行室有空位
来考虑了,就是说,Main Queue
等待block
完成再进行的这一个链条解开了,那么整个死锁的环就可以得以解开,从而解决了死锁问题。
3.一句话总结同步/异步和串行/并发的区别
同步/异步
是把怎么样任务放在处理队列中(要不要等待队列中的任务完成之后再放
),串行/并发
是处理队列的方式(要不要一个一个任务来做
)。
也就是说,并发其实是一下子搞任务A,一下子搞任务B,让你看上去像是同时搞一样。而串行就是,我一定要搞完任务A再搞任务B。同步就是,我一定要等你的队列里面的任务全部搞定
之后再给你新任务;异步就是,我管你队列里的任务完成没有,反正就是要加。
4.并行
参考这篇文章
其实并行和并发的根本区别就是有几个CPU
在搞这个任务。
并行是真的有这么多个CPU
同时在搞(多个线程放在不同核上同时跑)
并发是只有一个CPU
,只不过他这个CPU时不时切换一下任务(单核高频切换,使得用户觉得多个进程同时执行)。

从线程的角度来看,并发和并行的效果是一样的(都是同时来搞我),但是从上帝角度来看,并发和并行有着本质上的区别呢~
网友评论