一、造成线程堵塞的条件:
1、当前串行队列有任务。
2、在这个任务中使用同步函数给当前串行队列添加新的任务。
使用异步或者并行队列都不会造成死锁。
线程是所有任务的大集合,具体执行是在相应的队列中。
新等旧,旧等新,造成死锁。
同步和异步最大区别:
是否会阻塞当前线程,同步会立即执行当前任务,等待任务完成之后才继续进行其他任务,而异步不会阻塞线程,只是开始执行自己的任务,线程还会继续下面的操作,不用等待异步任务完成。
- GNUstep是GNU计划的项目之一,它将Cocoa的OC库重新开源实现了一遍
- 源码地址:http://www.gnustep.org/resources/downloads.php
- 虽然GNUstep不是苹果官方源码,但还是具有一定的参考价值
什么时候会产生死锁?
使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)
- (void)test01{
// 问题:以下代码是在主线程执行的,会不会产生死锁?会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
// 打印结果:直接跳转到堆栈列表,报错:Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
}
- (void)test02{
// 问题:以下代码是在主线程执行的,会不会产生死锁?不会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"执行任务2");
});
NSLog(@"执行任务3");
// 打印结果:执行任务1
// 执行任务3
// 执行任务2
}
- (void)test03{
// 问题:以下代码是在主线程执行的,会不会产生死锁?会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{ // 0
NSLog(@"执行任务2");
dispatch_sync(queue, ^{ // 1
NSLog(@"执行任务3");
});
NSLog(@"执行任务4");
});
NSLog(@"执行任务5");
// 打印结果:直接跳转到堆栈列表,报错:Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
//假如加入另一个串行队列2,在队列1中同步在队列2中添加任务,不会造成死锁
//只有在同一个串行队列中同步执行才回死锁。
}
- (void)test04{
// 问题:以下代码是在主线程执行的,会不会产生死锁?不会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_SERIAL);
// dispatch_queue_t queue2 = dispatch_queue_create("myqueu2", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue2 = dispatch_queue_create("myqueu2", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{ // 0
NSLog(@"执行任务2");
dispatch_sync(queue2, ^{ // 1
NSLog(@"执行任务3");
});
NSLog(@"执行任务4");
});
NSLog(@"执行任务5");
// 打印结果:执行任务1
// 执行任务5
// 执行任务2
// 执行任务3
// 执行任务4
//同步会阻塞线程,必须要完成之后才能继续接下来的任务
}
- (void)test05{
// 问题:以下代码是在主线程执行的,会不会产生死锁?不会!
NSLog(@"执行任务1");
dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{ // 0
NSLog(@"执行任务2");
dispatch_sync(queue, ^{ // 1
NSLog(@"执行任务3");
});
NSLog(@"执行任务4");
});
NSLog(@"执行任务5");
// 打印结果:执行任务1
// 执行任务5
// 执行任务2
// 执行任务3
// 执行任务4
//并发队列不会造成死锁。
}
网友评论