由于太多的“线程唤醒”,我的应用程序崩溃了。例如:
在过去的220秒内完成45004次唤醒(每次唤醒205次) 第二次平均值),超过300秒每秒超过150次唤醒这很难调试,因为我知道没有直接的方法来测量线程唤醒。我发现的最接近的是名为System Trace的Instruments模板,它将显示被阻塞的线程事件的数量。据推测,这是密切相关的,因为被阻塞的线程意味着该线程将被休眠,然后在它被解除阻塞时唤醒。
关于这一点的奇怪之处在于,当应用程序正常运行且没有崩溃时,被阻止的线程数在每秒10,000的范围内。我的假设是,在某些情况下,被阻塞的睡眠线程仅计入您的“唤醒”限制 - 例如我希望由于互斥锁而被锁定的线程计数,而操作系统只是在正常操作中转换到其他线程不会。
如果Instruments有一个Thread Wakeups模板,对我来说会很棒。我能找到的唯一文档就在这里 - https://developer.apple.com/library/content/technotes/tn2151/_index.html:
异常子类型
WAKEUPS
表示进程中的线程每秒被唤醒的次数太多,这会迫使CPU经常唤醒并消耗电池寿命。通常,这是由线程到线程的通信(通常使用
peformSelector:onThread:
或dispatch_async
)引起的,这种通信在不知不觉中发生的频率远远超过它应该发生的频率。因为触发此异常的通信类型经常发生,所以通常会有多个背景线程具有非常相似的Backtraces - 指示通信的来源。
答案 0 :(得分:0)
请看这里 https://developer.apple.com/forums/thread/124180 有一个在您的应用程序中获取唤醒计数的代码的描述,而不仅仅是在仪器中。可以帮到你:
#include <mach/task.h>
#include <mach/mach.h>
BOOL GetSystemWakeup(NSInteger *interrupt_wakeup, NSInteger *timer_wakeup) {
struct task_power_info info = {0};
mach_msg_type_number_t count = TASK_POWER_INFO_COUNT;
kern_return_t ret = task_info(current_task(), TASK_POWER_INFO, (task_info_t)&info, &count);
if (ret == KERN_SUCCESS) {
if (interrupt_wakeup) {
*interrupt_wakeup = info.task_interrupt_wakeups;
}
if (timer_wakeup) {
*timer_wakeup = info.task_timer_wakeups_bin_1 + info.task_timer_wakeups_bin_2;
}
return true;
}
else {
if (interrupt_wakeup) {
*interrupt_wakeup = 0;
}
if (timer_wakeup) {
*timer_wakeup = 0;
}
return false;
}
}
此外,您还可以找到唤醒发生次数过多的一些原因。