我遇到了一个非常奇怪的问题,它影响了仅在 OSX 10.10 系统上运行的代码。我已经在运行我的代码的超过 25 个 OSX 10.10 系统上看到了这种异常情况,而完全相同的代码在升级 (10.7) 之前没有表现出这种行为。此外,这个问题不是 100% 可重现的,因为它随机发生 ~0-5% 的时间。在测试代码时,机器上没有发生任何其他关键或 CPU 耗尽的情况。即使发生了其他事情,我所经历的延误实在是太可笑了,这一事实让这个结论看起来很可疑。无论如何,事不宜迟,看看下面的 NSLog 打印:
12:00:05.766 MyApp[59957:6540517] Time_To_Wait: 679000000, Fire_Date: 270946738287700, Cur_Date: 270946059302734
12:00:26.446 MyApp[59957:6540517] Resume...
时间以纳秒为单位。根据 NSLog 时间戳,我们实际上最终等待了 20.68 秒,而不是期望的 0.679 秒。现在,让我们看一下代码:
NSLog(@"Time_To_Wait: %lld, Fire_Date: %lld, Cur_Date: %lld", time_to_wait, fire_date, mach_absolute_time());
mach_wait_until(fire_date);
NSLog(@"Resume...");
如果您想知道 mach_wait 是什么,它是一个高分辨率计时器可用的默认值。只包括
#include <mach/mach.h>
#include <mach/mach_time.h>
但这并不重要,因为如果我将mach_wait_until替换为:
sleep()
usleep()
[NSThread sleepForTimeInterval:]
GCD's dispatch_after(,^{});
mach_wait_until()
不管我尝试使用哪种延迟方法,我NSLog
都会将我的“延迟”值打印到控制台作为健全性检查,以确保它是正确的毫秒数,然后触发上述方法之一。约 95% 的时间它的行为符合规范。但偶尔会随机出现 10-20 秒的延迟。是什么赋予了?这是一些优胜美地内核问题吗?同样,我从来没有经历过在 10.7 上运行相同代码的情况。而且我已经测试了上述所有延迟代码执行的方法。
更新:
根据评论建议,我继续前进sudo dtruss -f -e sudo -u USER MyApp 2> ~/myapps.log
。像往常一样,大多数 mach_wait 和 sleep 都按照他们应该的方式行事。所以为了让事情更容易识别,我添加了一个检查,如果实际睡眠持续时间 > 3x 它应该是什么,它会打印出 DELAY ISSUE。运行我的程序并搜索延迟问题。下面列出了在 mach_wait 语句之前和之后的日志打印之间发生的最频繁的系统调用(dtruss 输出):
- 99613/0xcf33b9: 30250 __semwait_signal(0xD07, 0x0, 0x1) = -1 Err#60
- 99613/0xcf33b9: 16 workq_kernreturn(0x20, 0x0, 0x1) = 0 0
上述两个电话中大约有 250 多个。可能比 __semwait 多一些 workq。semwait 通常需要大约 30000 个“单位”的时间才能完成,不管是什么。不知道如何 dtruss 时代。这些构成了呼叫的大部分。
- 752/0xcf3320: 2787191 kevent64(0x3, 0x0, 0x0) = 1 0
- 752/0xcf335d:189948 选择(0x40、0x7FC080E18220、0x7FC080E13B40、0x0、0x0)= 1 0
- 752/0xcf335d:1648403 选择(0x40、0x7FC080E18220、0x7FC080E13B40、0x0、0x0)= 1 0
这三个系统调用花费了最长的 # 个时间单位。在我们约 20 秒的等待间隙中,它们每个都出现在输出中一次。
不知道如何处理上面的=X