美文网首页从一开始——我的iOS学习之路
同步/异步,串行/并发,并行

同步/异步,串行/并发,并行

作者: 肠粉白粥_Hoben | 来源:发表于2018-07-12 18:09 被阅读6次

    回来又复习了一下自己之前的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时不时切换一下任务(单核高频切换,使得用户觉得多个进程同时执行)。

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

    相关文章

      网友评论

        本文标题:同步/异步,串行/并发,并行

        本文链接:https://www.haomeiwen.com/subject/gsirpftx.html