GCD死锁

GCD死锁原因

GCD死锁的原因是队列阻塞,而不是线程阻塞!

串行和并行

串行和并行都是相对于队列而言的
-队列(负责调度任务)
-串行队列:一个接一个的调度任务
-并发队列:可以同时调度多个任务
在使用GCD的时候,我们会把需要处理的任务放到Block中,然后将任务追加到相应的队列里面,这个队列,叫做Dispatch Queue
队列一般存在于两种Dispatch Queue,
一种是要等待上一个执行完,再执行下一个的Serial Dispatch Queue,这叫做串行队列;
另一种,则是不需要上一个执行完,就能执行下一个的Concurrent Dispatch Queue,叫做并行队列。
这两种,均遵循FIFO原则,也就是先进先出原则。

同步与异步

串行与并行针对的是队列,而同步与异步,针对的则是线程
最大的区别在于,同步线程要阻塞当前线程,必须要等待同步线程中的任务执行完,返回以后,才能继续执行下一任务;而异步线程则是不用等待。

GCD API

1.系统标准提供的两个队列

// 全局队列,一个特殊的并行队列
dispatch_get_global_queue
// 主队列,在主线程中运行,因为主线程只有一个,所以这是一个特殊的串行队列
dispatch_get_main_queue

2.除此之外,还可以自己生成队列

// 从DISPATCH_QUEUE_SERIAL看出,这是串行队列
dispatch_queue_create("com.demo.serialQueue", DISPATCH_QUEUE_SERIAL)
// 同理,这是一个并行队列
dispatch_queue_create("com.demo.concurrentQueue", DISPATCH_QUEUE_CONCURRENT)

3.同步与异步线程的创建:

dispatch_sync(..., ^(block)) // 同步线程
dispatch_async(..., ^(block)) // 异步线程

案例

1.会产生死锁

NSLog(@"1"); // 任务1
dispatch_sync(dispatch_get_main_queue(), ^{
    NSLog(@"2"); // 任务2
});
NSLog(@"3"); // 任务3

2.不会产生死锁

dispatch_queue_t queue = dispatch_queue_create("ent.nensl.sda", DISPATCH_QUEUE_SERIAL);
    
NSLog(@"111111");
dispatch_sync(queue, ^{
        NSLog(@"222222————%@",[NSThread currentThread]);
 });
    
NSLog(@"333333");

ent.nensl.sda这个队列的执行线程是主线程,同步方式不会开辟新线程,但这是我们是将任务添加到了ent.nensl.sda这个队列中,所以主线程会来立即执行这个队列中的任务,执行完成后就会返回,主线程不会继续被阻塞。所以不会死锁。

你可能感兴趣的:(GCD死锁)