コメントの1つで述べたように、POSIX clock_gettime()
はiOS10とmacOS10.12に実装されました。引数とともに使用するとCLOCK_MONOTONIC
、稼働時間の値を返すように見えます。ただし、これはドキュメントによって保証されていません。
このクロックの場合、clock_gettime()によって返される値は、過去の不特定の時点(たとえば、システムの起動時間やエポック)からの時間(秒とナノ秒)を表します。このポイントは、システムの起動時間後も変わりません。
そして、対応するmacOSのマニュアルページからの抜粋:
CLOCK_MONOTONICクロックは単調に増加し、任意のポイントからの時間を追跡し、システムがスリープしている間も増加し続けます。
CLOCK_MONOTONIC_RAWクロックは単調に増加し、CLOCK_MONOTONICのような任意のポイントからの時間を追跡します。ただし、このクロックは周波数や時間の調整の影響を受けません。他のシステムタイムソースと比較しないでください。
CLOCK_MONOTONIC_RAW_APPROXはCLOCK_MONOTONIC_RAWに似ていますが、コンテキストスイッチでシステムによってキャッシュされた値を読み取ります。これはより速く読み取ることができますが、ミリ秒前の値を返す可能性があるため、精度が低下します。
CLOCK_MONOTONIC_RAWと同じように単調に増加するが、システムがスリープしている間は増加しないCLOCK_UPTIME_RAWクロック。戻り値は、適切なmach_timebase変換が適用された後のmach_absolute_time()の結果と同じです。
ナノ秒の精度であるのCLOCK_MONOTONIC
に対し、マイクロ秒の精度で戻ることに注意してください。CLOCK_MONOTONIC_RAW
スウィフトコード:
func uptime() -> timespec {
var uptime = timespec()
if 0 != clock_gettime(CLOCK_MONOTONIC_RAW, &uptime) {
fatalError("Could not execute clock_gettime, errno: \(errno)")
}
return uptime
}
print(uptime()) // timespec(tv_sec: 636705, tv_nsec: 750700397)
Swiftでカーネルの起動時間を取得することにまだ興味がある人のために:
func kernelBootTime() -> timeval {
var mib = [ CTL_KERN, KERN_BOOTTIME ]
var bootTime = timeval()
var bootTimeSize = MemoryLayout<timeval>.size
if 0 != sysctl(&mib, UInt32(mib.count), &bootTime, &bootTimeSize, nil, 0) {
fatalError("Could not get boot time, errno: \(errno)")
}
return bootTime
}
print(kernelBootTime()) // timeval(tv_sec: 1499259206, tv_usec: 122778)