2

OSX 10.10 システムでのみ実行しているコードに影響する非常に奇妙な問題に遭遇しました。私のコードを実行している 25 以上の OSX 10.10 システムでこの異常が発生するのを見てきましたが、アップグレード (10.7) する前はまったく同じコードでこの動作は見られませんでした。さらに、この問題は 0 ~ 5% の確率でランダムに発生するため、100% 再現可能ではありません。コードをテストしている間、マシン上で他に重要なことや 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 タイムスタンプによると、実際には、必要な 0.679 秒ではなく、20.68 秒待機することになりました。それでは、コードを見てみましょう。

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 秒のような遅延が発生します。何を与える?これは Yosemite カーネルの問題ですか? 繰り返しますが、10.7 で実行されている同じコードでこれを経験したことはありません。そして、コードの実行を遅らせるために上記のすべての方法をテストしました。


アップデート:

コメントのアドバイスに従って、私は先に進みましたsudo dtruss -f -e sudo -u USER MyApp 2> ~/myapps.log. いつものように、ほとんどの mach_wait と sleep は想定どおりに動作しました。そのため、識別しやすくするために、実際の睡眠時間が本来の 3 倍を超える場合に 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

上記の 2 つの呼び出しが約 250 以上あります。おそらく、__semwait よりも少し作業量が多くなります。通常、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

これら 3 つのシステム コールは、時間の単位数が最も長くかかりました。そして、それらはそれぞれ、約 20 秒の待機ギャップ中に出力に 1 回表示されました。

上記の =X をどうするかわからない

4

1 に答える 1

3

上記のコメントを参照してください

この問題は、Apple のTimer Coalescing に関連しているようです。Mac OS X 10.9 Mavericks の新機能で、タイマーの起動時間を最大数ミリ秒調整してマージし、プロセッサが電源状態の遷移を少なくして、アイドル状態が長くなります。メリットは、消費電力が大幅に削減されることです。

それについて簡単に言及しているトピックに関する Apple のホワイト ペーパーは、こちらです。

コメントに残されている解決策は、次のように TC を無効にすることです。

sudo sysctl -w kern.timer.coalescing_enabled=0
于 2015-03-03T01:41:37.967 に答える