我正在使用GCD对SQL数据库执行大量数据提交和数据读取操作,我创建了串行队列并执行我正在使用dispatch_async
的操作。
队列创建代码:
self.dataBaseQueue = dispatch_queue_create("com.myAPP.dataBaseQueue", DISPATCH_QUEUE_SERIAL);
执行代码
dispatch_async(self.dataBaseQueue, codeblock);
codeblock包含数据库操作读取或写入。
现在,当我记录队列的debugDescription
时,它正在打印
OS_dispatch_queue: com.myAPP.dataBaseQueue[0x1cd58ae0] = { xrefcnt = 0x1, refcnt = 0x1, suspend_cnt = 0x0, **locked = 0**, target = com.apple.root.default-overcommit-priority[0x3d335300], width = 0x0, running = 0x0, barrier = 0 }
经过一些操作后,它正在打印
OS_dispatch_queue: com.myAPP.dataBaseQueue[0x1cd58ae0] = { xrefcnt = 0x1, refcnt = 0x1, suspend_cnt = 0x0, **locked = 1**, target = com.apple.root.default-overcommit-priority[0x3d335300], width = 0x0, running = 0x0, barrier = 0 }
那么locked =1
和locked =0
是什么意思?
答案 0 :(得分:2)
正如yurish所指出的那些消息来源可用,但无论如何“让我为你做谷歌”,还有一些(希望是有用的)补充分析。
首先,一些背景......在object_internal.h
中,您可以找到以下#define
:
#define DISPATCH_OBJECT_SUSPEND_LOCK 1u
#define DISPATCH_OBJECT_SUSPEND_INTERVAL 2u
#define DISPATCH_OBJECT_SUSPENDED(x) \
((x)->do_suspend_cnt >= DISPATCH_OBJECT_SUSPEND_INTERVAL)
这表明单个值将与这些#define
一起使用,以使其作为锁定位(在LSB中)和暂停计数(在其余部分中)执行双重任务比特。)
然后,在object.c
中,我们可以看到实际实现此调试消息业务的位置:
size_t
_dispatch_object_debug_attr(dispatch_object_t dou, char* buf, size_t bufsiz)
{
return snprintf(buf, bufsiz, "xrefcnt = 0x%x, refcnt = 0x%x, "
"suspend_cnt = 0x%x, locked = %d, ", dou._do->do_xref_cnt + 1,
dou._do->do_ref_cnt + 1,
dou._do->do_suspend_cnt / DISPATCH_OBJECT_SUSPEND_INTERVAL,
dou._do->do_suspend_cnt & 1);
}
果然,我们发现suspend_cnt
对应dou._do->do_suspend_cnt / DISPATCH_OBJECT_SUSPEND_INTERVAL
而locked
对应dou._do->do_suspend_cnt & 1
,因此很容易得出结论,是的,do_suspend_cnt
正在做这个双重职责由上述#define
暗示。
现在,我们可以在消息来源中观察到do_suspend_cnt
仅在queue.c
中的少数几个地方被引用。在队列结构的初始化中提到了它。它也被barrier
调用使用,但仅在DISPATCH_OBJECT_SUSPEND_INTERVAL
递增和递减方面使用,所以这并不重要(至少不是关于锁定位 - 有人可能认为这个障碍很有意思dispatch是通过挂起队列来实现的,直到屏障调用返回,但这不是OP所要求的)。
我看到的剩余提及是在_dispatch_wakeup
中,它似乎在将下一个工作项从队列中移除之前以原子方式设置锁定位(有道理,对吗?不要从队列中取出以下内容一个地方同时)然后再次在_dispatch_queue_invoke
中减去锁定位,似乎在_dispatch_wakeup
中平衡它的设置。最后,我们在_dispatch_queue_cleanup2
中看到它(在表面上)看起来像主要调度队列的一次性拆解工作。
所以你有它。调试描述中locked =
的出现暴露了libdispatch
似乎用于保护其内部数据结构免于并发突变的内部锁定位的状态。作为libdispatch
的用户,这可能对您没有任何影响。