출처: https://zenn.dev/avita_blog/articles/8c6f043217ea05

wall clock 와 monotoric clock 이라는 것은?

현대 컴퓨터에는 적어도 두개의 시간이 있다.

하나는 시각 시간(wall clock)이고 다른 하나는 단조증가 시간(monotonic clock) 이다.

wall clock란 캘린더를 기준으로 현재 날짜, 시간을 나타낸다. 한편으로는 monotonic clock은 항상 계속 진행하는 시간을 가리킨다 (스톱워치 등을 생각하면 좋다).

wall clock는 일반적으로 NTP 서버와 동기화된다. 즉, 한 머신의 타임스탬프는 다른 머신의 타임스탬프와 같은 시간을 가리킨다.

monotonic clock는 어느 시간을 기점으로 시간을 단조 증가시킨 것이다. (스톱워치라면 0초를 기점으로 시간이 늘어나간다)

wall clock는 현재 날짜와 시간이 언제인지 알아내는 데 적합하고, monotonic clock는 기간을 조사하는데 적합하다.

Go에서도 1.9부터 이 monotonic clock 이 지원된다.

time package wall clock와monotonic clock

Go의 time package는 Time 구조체를 반환하지만 이 구조체에는 wall clock 과 monotonic clock 이 포함 되어 있다.

현재 시간을 얻기 위해 아래를 수행하는 경우가 많다.

time.Now()

여기는 Time 구조체를 반환한다.

Time 구조체에 Duration을 Add() 해보자.

t0 := time.Now()               // 2009-11-10 23:00:00 +0000 UTC m=+0.000000001
t1 := t0.Add(10 * time.minute)
// 2009-11-10 23:10:00 +0000 UTC m=+600.000000001

그러면 현재 시간보다 10분이 진행된 다른 Time 구조체를 얻을 수 있다.

여기서 t0 과 t1로 표시된 시간을 살펴보자.

옆에 m = +hogehoge 라고 표시된다.

이것이 Go에서의 monotonic clock 이다. 또, 그 이전의 시각을 나타내고 있는 것이 wall clock 이다.

여기서 m=+0.000000001 이 궁금한 분도 있을지도 모르겠다. 이것은 프로그램이 실행하는데 걸린 시간이므로 별로 신경 쓰지 말자.

여기서 두 시간의 차이를 살펴 보겠다.

t2 := t1.Sub(t0) // 10m0s

추가한 시간만의 차이가 표시 되었다. 이 차이는 monotonic clock에 따라 계산된다.

하지만 monotonic clock 은 언제든지 사용할 수 있는 것은 아니다. monotonic clock가 사라져 버리는 메소드 (AddDate, Round, Truncate 등)가 몇개 존재한다.

t3 := t0.Round(0) // 2009-11-10 23:00:00 +0000 UTC

이렇게 monotonic clock 이 사라진 상태에서 Sub 메소드를 실행하면 monotonick clock 대신에 wall clock 으로 처리가 실행되므로 조심하자.

요약

Go wall clock 과 monotonic clock 에 대해 해설했다. 시간을 조사할 때는 wall clock을 사용하고, 기간을 조사할 때는 monotonic clock을 사용하고 있다. Time 구조체에 구현되고 있는 메소드에는 monotonic clock을 지워 버리는 메소드도 존재하므로 조심하자.