另外还有一些问答,和我当前疑问并不直接相关所以略去。最后再贴一段比较有意思的回复,在阅读之前大家可以自己先思考下:
dispatch_async(myQueue, ^{
// line A
});
// line B
line A 和 line B 谁先执行?
Consider a snippet like this:
dispatch_async(myQueue, ^{
// line A
});
// line B
there's clearly a race condition between lines A and B, that is, between the `dispatch_async` returning and the block running on the queue. This can pan out in multiple ways, including:
* If `myQueue` (which we're assuming is a serial queue) is busy, A has to wait so B will definitely run before A.
* If `myQueue` is empty, there's no idle CPU, and `myQueue` has a higher priority then the thread that called `dispatch_async`, you could imagine the kernel switching the CPU to `myQueue` so that it can run A.
* The thread that called `dispatch_async` could run out of its time quantum after scheduling B on `myQueue` but before returning from `dispatch_async`, which again results in A running before B.
* If `myQueue` is empty and there's an idle CPU, A and B could end up running simultaneously.
答案
其实最后我也没有得到我想要的准确的答案,可能正如回复里所说,情况有很多而且过于复杂,没法通过一个用户态的 call stack 简单推知内核的状态,但有些有价值的信息还是得以大致理清:
信息一
iOS 系统本身是一个资源调度和分配系统,CPU,disk IO,VM 等都是稀缺资源,各个资源之间会互相影响,主线程的卡顿看似 CPU 资源出现瓶颈,但也有可能内核忙于调度其他资源,比如当前正在发生大量的磁盘读写,或者大量的内存申请和清理,都会导致下面这个简单的创建线程的内核调用出现卡顿:
libsystem_kernel.dylib __workq_kernreturn
所以解决办法只能是自己分析各 thread 的 call stack,根据用户场景分析当前正在消耗的系统资源。后面也确实通过最近提交的代码分析,发现是由于增加了一些非常耗时的磁盘 io 任务(虽然也是放在在子线程),才出现这个看着不怎么沾边的 call stack。revert 之后卡顿警报就消失了。










