问题:ios 谁能分析下多线程死锁问题,感谢,分析图一二为什么是这个结果?
(问题帖子链接:http://zhidao.baidu.com/link?url=Lr9sNchrdnCLJdoc73WeHfL3lcu7lBvyKQ2hBrF2jbyM3wkJWeK0esMKOhIVL9wDfwOduh7pK3UCIwxreRBZjeyv0uYZpnCxR7dms05Ih4K)
网络看到一个帖子(链接如上)关于多线程死锁问题,我挺感兴趣,由此对这个问题做了回答,我参考了帖子中的答案
我的回答:
我采用分解法(把一个问题分解为多个问题),为什么多线程会发送死锁,由此我提出如下问题:
1, 串行queue 与并行queue的各自特点?
2, queue与线程什么关系?
3, dispatch_sync() 与dispatch_async()函数实现?(后面有我自己的猜想实现)
答:
1:
1) 串行queue 和 并行queue本质都是一个链表(或是数组),就用来存放任务(block)。
2)串行queue有锁,并行queue没有锁
2:
串行queue:
1)线程会按添加任务的顺序依次取出串行queue中的任务(block),然后执行,只有执行完一个任务,才能执行下一个任务。
2)线程在执行任务之前会上锁,执行完任务后会解锁
并行queue:
1)线程取出并行queue中任务,并且会创建新线程来执行任务。
2)线程执行任务的时候不会上锁、解锁,就直接执行任务
3:dispatch_sync和dispatch_async的伪代码实现
dispatch_sync(queue,block)
{
// 锁
if(queue == 串行队列)
{
//是串行队列,才上锁
lock(queue.lock);//每个串行queue都拥有自己唯一的锁lock
}
//调用block
block();
//解锁
if(queue == 串行队列)
{
//是串行队列,才解锁
unlock(queue.lock)
}
}
dispatch_async(queue,block)
{
if(queue != mainQueue)
{
创建新线程,执行所有下面的代码
}else{
不会创建新线程,直接执行所有下面的代码
}
// 锁
if(queue == 串行队列)
{
//是串行队列,才上锁
lock(queue.lock);//每个串行queue都拥有自己唯一的锁lock
}
//注意:dispatch_async比dispatch_sync多了如下操作
if(queue == 并行队列)
{
//是并行队列,创建新线程
dispatch_thread_t newThread = create_thread();
// 在新线程中运行任务(block)
newThread.run(
//调用block
block();
);
}else{ //不是并行队列
//调用block
block();
}
//解锁
if(queue == 串行队列)
{
//是串行队列,才解锁
unlock(queue.lock)
}
}
知道以上情况,那我们就拿第一个例子解释:如下图
答案解析:
//新建了一个串行队列并标识为”queue”
dispatch_queue_t queue = dispatch_queue_create(“queue”,DISPATCH_QUEUE_SERIAL);
dispatch_aysnc(queue,^{ //设此block为A,则A被添加到queue
if(queue != mainQueue)
{
创建新线程,执行所有下面的代码
}else{
不会创建新线程,直接执行所有下面的代码
}
//红色为系统默认操作,代码里没有的
if(queue == 串行队列)
{
//是串行队列,才上锁
lock(queue.lock);//成功上锁
}
NSLog(@”%@---1”,[NSThreadcurrentThread]);
Dispatch_sync(queue,^{ //设此block为B,则B被添加到queue
//红色为系统默认操作,代码里没有的
if(queue == 串行队列)
{
lock(queue.lock);//B不能上锁,因为A已经Lock,而且A还没unlock
//由此造成死锁:B此时会等待A unlock但是A的unlock必须等B执行
完才会调用,所以永远B都会在等待A,A又在等B执行完……..
// 这里有个重点:queue.lock每个queue有自己唯一的lock
所以只有同一个queue的任务(block)才会造成死锁,因为lock()的参数,如果是不同的锁,肯定是可以上锁成功的,你懂了吗?
}
NSLog(@”%@---2”,[NSThreadcurrentThread]);
//红色为系统默认操作,代码里没有的
if(queue == 串行队列)
{
unlock(queue.lock);//
}
});
dispatch_async(queue,^{
NSLog(@”%@---3”,[NSThreadcurrentThread]);
});
// 红色为系统默认操作,代码里没有的
if(queue == 串行队列)
{
unLock(queue.lock);
}
});