iOS GCD 队列与线程

        篇幅有点长,持续补充中。

        首先我们要明白一个东西,队列是队列,线程是线程,在队列里执行代码,可能会创建新的线程,下面我们通过几种case,来说明常见的一些情况.一切以实际测试情况为准.

    1. 串行队列,同步执行

    case1.

        从主线程,开始执行,结果是不会创建新的线程,顺序执行,由此可以推测,在另外一个线程里面,也只这样,不会创建线程,在当前线程,顺序执行.我们再测试另外一种case,从不同的线程,进入一个同步队列,串行执行,结果会怎样呢?

case2.

        上诉结果说明两个事实:

        1. 并不是111,222,333,444,555,666 这样执行的,为什么,因为是通过global async 加进去的,并行加入的顺序,不一定是123456,所以执行的顺序是,加入的顺序,这里是 134256

         2. 执行的线程,是从global 加入线程里执行的,这里很明显就表示,线程是线程,队列是队列,不管你从哪个线程加入的,在串行队列里,就是那个先来,就执行那个.

2. 串行队列,并发执行

    case3. 代码如下:

        

以上结果说明,串行队列,并行执行,结果无非是新开了一个线程,再在这个新的线程里面串行执行。

    case4. 


       与case2 基本一致,谁先来,谁先进入队列去排队,就好比从10条车道上来了10辆车,进入一个加油站,加完油,选择同一条路(同一个线程,这个线程是随机分配的,但是一定是同一条)出去,车子谁先来,就谁先进加油站。但是看打印发现一个问题,车子来的顺序是 1230546789,车子出去的顺序是 1230564789,6和4顺序反了,这是什么情况,经过多次测试,发现,大部分情况是一致的,我的猜测是,打印的顺序与车子实际到达加油站的顺序是有误差的,也就是,6 实际比4线到达,但是4 比6 先报备,至于怎么解决这个误差,以后再研究。

        总之,同步队列,就是谁先到谁先执行。dispath_async 只不过是开辟一个新的线程,去串行执行而已,dispath_sync ,则就是添加任务的线程,串行去执行。

        diapathch_async(global,{  })的方式去给同步队列添加任务,结果还是,谁先添加进来,谁先执行,只不过添加进来的任务顺序随机罢了,如case2,case4.

3. 并行队列,串行执行

        case5. 

        结果和case1 一样,所以在这种case下,和case1是一摸一样的(其实内部肯定有不一样,后面会有case说明),相当于,一个加油站,可以允许很多辆车同时进来,但是你就一条道,挨个进来,那我只能挨个出去了

    case 6. 并行队列,串行执行,但是,是并行加入任务的


       打印结果,执行thread===  的顺序是 0231567849,执行 thread i 的顺序是2031564879,这任务4 也延后太多了吧,也就是任务4很早就加入了,但是很晚才执行,说明什么,说明,dispatch_sync(queue,^{ });里面执行的任务,没有相互等待,也就是,这个queue ,是并行的队列,即使是sync 执行,sync 表示在加入他们的地方,是串行执行的,也就是,NSLog(@"thread=== %d:%@",i,[NSThread currentThread]); 和 他紧挨着的 dispatch_sync(queue,^{ });任务是串行执行的,而不同的dispatch_sync(queue,^{ }); 之间并没有相互等待,就好比,10辆车,先后进加油站,进了之后各自加油,然后各自出去,并不是一辆车加完油出去了,另外一辆车才能进来加油,怎么证明我的说法呢,看他们是否相互等待就行了,看以下代码:


0 并没有等待1 执行完之后再执行,其实这种写法的执行效果,和下面这种写法是一个道理,只不过把任务加入到queue里面执行罢了:


        那既然这样,那加入到queue 还有什么意义呢,有!比如我们一个数据,很多线程都在读和写,如果只控制写的地方,比如对写的地方加锁,还是有问题,什么问题呢,加锁只是对 写的代码块儿加锁,也就是,写是串行的了,但是写的同时其他线程还有可能在读啊,也就是本来这一刻我应该读的是数据时1,你同时还在操作这个指针,让他指向2,那么我读出来的该是1 还是2呢。而加入队列的话,可以解决这个问题,写的时候,加入队列栏杆(iOS 上叫dispatch_barrier_async),这样写的时候,读全部停下来,写完之后,你再继续,这样就不会读写冲突了。上面的代码还可以验证case4 ,证明case4结论是正确的.

case7 . 并行队列,async 执行


          这种case,就很好理解了,各自进,各自出,不想关,线程有queue 自己分配,可能在一个,也可能不是一个.这种case,理解为,一个车道上进入加油站,有很多油箱,一个一个的进加油站,但是自己加完自己走,走的道也有很多条,谁先走,看谁先加完。

case8 . 并行队列,async 执行,而且加入的时候,都是不同的线程加的。


           这种case 也很好理解,场景也很普通,不同的线程,async 一个并行队列,去做一些事,如果需要控制这些事之间的依赖关系,可以加group 或者dispatch_barrier_async来控制。这就好比,很多个车道,车辆先后进入,加油站有很多加油位,自己加完,自己走。


            以上8中case ,基本整理完,并行、串行、async、sync 各种执行case,下面再来说一种case ,死锁。

  case9.

        第一种死锁,串行队列,串行执行

                 

        这个很好理解,串行队列里,事件1 等待事件2完成,事件2等待事件1完成,相互等待,死锁

case 10.

        串行队列,async 执行,代码如下:


        相当于,新开了一个线程,在这个线程里面,相互等待,死锁

case 11.

    

         这种情况下,没有死锁,为什么,queue 执行事件1, 过程中,新开了一个线程,把线程里面的任务2,异步加入到队里里面,任务1 执行完之后,在异步的执行任务2,没有问题。

case12. 并发队列,但是同步执行

        

        理论上,并行队列,但是队列里面的任务还是同步执行,应该相互等待,然而结果不是,打印结果是打印完 j 再打印k,说明什么,说明,并行队列,执行过程中,串行的加入任务,这个任务居然插队了,不用等待前一个任务完成就执行,很神奇,可能是 并行队列做了处理,我也希望有人给我解惑啊,将第一个diapath_async 换成 dispath_sync 结果一样,只是换到主线程执行而已!!!


        大致就是这样了,如果遇到新发现,我会及时更新的 !

你可能感兴趣的:(iOS GCD 队列与线程)