iOS-如何衡量线程唤醒?

use*_*430 6 multithreading instruments ios

我有一个因“线程唤醒”过多而崩溃的应用程序。例如:

最近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

请看这里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;
  }
}
Run Code Online (Sandbox Code Playgroud)

此外,您还可以找到唤醒发生次数过多的一些原因。