ios多线程死锁解析


问题: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,^{  //设此blockA,则A被添加到queue

                                            

if(queue != mainQueue)

  {

创建新线程,执行所有下面的代码

 }else{

不会创建新线程,直接执行所有下面的代码

}


 

            //红色为系统默认操作,代码里没有的

            if(queue == 串行队列)

  {  

     //是串行队列,才上锁

lock(queue.lock);//成功上锁

            }


            NSLog(@”%@---1”,[NSThreadcurrentThread]);

 

            Dispatch_sync(queue,^{ //设此blockB,则B被添加到queue

 

            //红色为系统默认操作,代码里没有的

 

            if(queue == 串行队列)

          {  

             lock(queue.lock);//B不能上锁,因为A已经Lock,而且A还没unlock

            //由此造成死锁:B此时会等待A unlock但是Aunlock必须等B执行

               完才会调用,所以永远B都会在等待AA又在等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);

}

 

});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值