博客> 关于dispatch_get_current_queue解决线程可重入遇到死锁的问题,以及"队列特有数据"解决可重入死锁问题
关于dispatch_get_current_queue解决线程可重入遇到死锁的问题,以及"队列特有数据"解决可重入死锁问题
2017-10-19 09:25 评论:0 阅读:115 诸葛亮倒骑小毛驴
dispatch_get_current_queue dispatch_set_target_queue dispatch_queue_set_specific dispatch_get_specific

dispatch_get_current_queue该方法自iOS系统6.0版本起,苹果公司已经正式启用该函数了,不过到目前为止还未正式将其废用,该函数能够拿到当前线程的是处于哪个线程,不过在涉及到方法可重入问题中,利用dispatch_get_current_queue进行线程判断并不会解决线程死锁问题,例如: dispatch_queue_t queueA = dispatch_queue_create("www.baidu.com", NULL); dispatch_queue_t queueB = dispatch_queue_create("www.baidu.com", NULL);

dispatch_sync(queueA, ^{
    dispatch_sync(queueB, ^{
        dispatch_block_t block = ^{
            NSLog(@"%@",@"我只是一个标记");
        };
        if (dispatch_get_current_queue() == queueA) {
            block();
        }else{
            dispatch_sync(queueA, block);
        }
    });
});

dispatch_get_current_queue能够处理一些简单的情况,对于复杂的线程交互问题,所存在的线程死锁问题还是有较大的风险,对于这种问题,利用"队列特有数据"就能解决复杂的线程交互问题,避免死锁现象,此功能可以把任意的数据以键值对的形式关联到队列中,假如根据指定的键值对找不到对应的关联数据,系统就会依次向上查找,知道找到数据或到达最基层,例如下面的例如: dispatch_queue_t queueA = dispatch_queue_create("www.baidu.com", NULL); dispatch_queue_t queueB = dispatch_queue_create("www.baidu.com", NULL);

 // 将queueB队列关联到queueA上
 dispatch_set_target_queue(queueB, queueA);

 static int kQueueSpecific;
 // 临时CFstring
 CFStringRef queueSpecificValue = CFSTR("queue");

 dispatch_queue_set_specific(queueA, &kQueueSpecific, (void *)queueSpecificValue, (dispatch_function_t)CFRelease);

 dispatch_sync(queueB, ^{
 // 创建临时block
 dispatch_block_t block = ^{
 NSLog(@"%@",@"queueB");
 };
 // 通过key地址获取(void*)值
 CFStringRef retrieveValue = dispatch_get_specific(&kQueueSpecific);

 if (retrieveValue) {
 block();
 }else{
 dispatch_sync(queueA, block);
 };
 });

在可重入的情况下,就避免了死锁现象,但是也不能一概而论,dispatch_get_current_queue和"队列特有数据"应该视情况而定,看问题的复杂度适合哪种解决办法.

收藏
2
sina weixin mail 回到顶部