我很难找到如何使用这些函数的好例子。
static void * kQueue1Key = "key1";
static void * kQueue2Key = "key2";
dispatch_queue_t queue1 = dispatch_queue_create("com.company.queue1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue2 = dispatch_queue_create("com.company.queue2", DISPATCH_QUEUE_SERIAL);
dispatch_queue_set_specific(queue1, kQueue1Key, (void *)kQueue1Key, NULL);
dispatch_queue_set_specific(queue2, kQueue2Key, (void *)kQueue2Key, NULL);
dispatch_sync(queue1, ^{
if(dispatch_get_specific(kQueue1Key))
{
NSLog(@"I'm expecting this line to run (A)");
dispatch_sync(queue2, ^{
NSLog(@"I'm expecting this line to run (B)");
if(dispatch_get_specific(kQueue2Key))
{
if(dispatch_get_specific(kQueue1Key))
{
NSLog(@"I'm expecting this line to run (C)");
}
else
{
[NSException raise:NSInternalInconsistencyException format:@"Should not end up here (C)"];
}
}
else
{
[NSException raise:NSInternalInconsistencyException format:@"Should not end up here (B)"];
}
});
}
else
{
[NSException raise:NSInternalInconsistencyException format:@"Should not end up here (A)"];
}
});
结果
I'm expecting this line to run (A)
I'm expecting this line to run (B)
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Should not end up here (C)'
这是预期的行为吗?如果我将dispatch_sync分派到queue1,因为我不在该队列上,我会死锁。我错过了什么?
dispatch_sync
实现递归锁?因为这条路最终会带来悲伤(简而言之:由于可能存在非默认队列的定向性,即使您假设您的队列没有被巧妙地定向,涉及到的辅助问题也会夺走大部分(甚至全部)标准递归锁的性能优势。)另请参见:https://dev59.com/lHjZa4cB1Zd3GeqPbDWy#19495517 - ipmccdispatch_get_specific
是避免互斥锁的“新答案”。如果不是,那它还能提供什么? - hfosslidispatch_queue_set/get_specific
只是提供了一个悬挂在队列上的任意关联存储。dispatch_get_specific
允许您在没有对当前队列的引用的情况下读取该存储。如果您有一个针对Qa的Qb,并在Qa上设置了特定值,然后从在Qb上执行的块中获取特定值,它将遍历目标链并返回来自Qa的值,其中包含一些附加功能。 - ipmcc-[NSThread threadDictionary]
的优秀替代品吗? - hfosslidispatch_queue_set/get_specific
的用途是,它是推荐使用的机制,可以替代现在已被弃用的dispatch_get_current_queue
函数。 - ipmcc