사전 단조 시계
개념

단조 시계

gabury1고친 사람 github-actions[bot]

단조 시계는 흘러간 시간만 재 주는 시계입니다. 값이 뒤로 가는 일이 없어서, 두 번 읽어 뺀 차이가 그동안 흐른 시간이 됩니다. 대신 오늘이 며칠이고 지금이 몇 시인지는 말해 주지 못합니다.

쉽고 빠른 이해

단조 시계는 스톱워치입니다. 눌러 두었다가 나중에 다시 보면 그 사이에 몇 초가 지났는지 알려 줍니다.

달력 시각을 알려 주는 시계는 가끔 뒤로 갑니다. 시각이 틀어지면 누군가 맞춰 주기 때문입니다. 그 시계로 걸린 시간을 재면 음수가 나오는 날이 옵니다.

  1. 일을 시작하기 전에 한 번 읽습니다
  2. 일이 끝나고 한 번 더 읽습니다
  3. 두 값을 빼면 걸린 시간입니다

대가는 값 하나만 떼어 놓고 보면 아무 뜻이 없다는 것입니다. 시작점이 기기마다 다르고 다시 켜면 처음으로 돌아가서, 로그에 남기거나 옆 기기의 값과 견줄 수 없습니다.

상세

손목에 찬 스톱워치와 벽에 걸린 시계는 하는 일이 다릅니다. 스톱워치는 버튼을 누른 뒤로 몇 초가 흘렀는지만 알려 주고, 누가 건드려도 바늘이 뒤로 돌아가지 않습니다. 벽에 걸린 시계는 지금이 몇 시인지 알려 주는 대신, 틀어지면 사람이 바늘을 돌려 맞춥니다. 단조 시계는 이 스톱워치 쪽입니다.

단조 시계는 한 방향으로만 가는 시계입니다. 두 번 읽어 뒤 값에서 앞 값을 빼면 그 사이에 흐른 시간이 나옵니다. 요청 하나를 처리하는 데 얼마나 걸렸는지, 응답을 얼마나 더 기다릴지를 재는 것이 이 시계가 맡는 일입니다.

값 하나만 떼어 놓고 보면 뜻이 없습니다. 0 이 언제인지가 정해져 있지 않아서입니다. 기기가 켜진 때를 0 으로 삼는 운영체제가 흔하지만, 어디를 0 으로 잡든 상관없다는 것이 이 시계의 약속입니다. 뜻을 지는 것은 두 값의 차이뿐입니다.

이 절은 차례로 봅니다. 벽시계와 무엇이 갈리는지, 벽시계가 왜 뒤로 가는지, 경과 시간을 어떻게 재는지, 운영체제가 어떤 이름으로 이 시계를 내주는지, 그리고 둘 중 어느 쪽을 골라야 하는지입니다.

벽시계와의 차이

벽시계는 오늘 날짜와 지금 시각을 알려 주는 시계입니다. 세상이 함께 쓰는 시각에 맞춰 두어야 뜻이 있어서, 틀어지면 맞춰 줍니다. 서버에서 로그에 찍히는 시각, 데이터베이스에 저장하는 만료 시각이 전부 이 시계에서 나옵니다.

두 시계는 답하는 물음부터 다릅니다. 하나는 「지금 몇 시인가」에 답하고, 다른 하나는 「얼마나 지났나」에 답합니다.

벽시계 단조 시계
답하는 물음 지금 몇 시인가 얼마나 지났나
0 이 언제인가 정해져 있다 정해져 있지 않다
뒤로 가나 간다 안 간다
옆 기기의 값과 견주기 된다 안 된다
다시 켠 뒤 이어진다 처음으로 돌아간다

표의 마지막 두 줄이 이 시계를 쓸 수 없는 곳을 정합니다. 시작점이 기기마다 다르니 두 서버의 값을 빼는 것은 뜻이 없고, 다시 켜면 값이 처음으로 돌아가니 오래 두고 쓸 만료 시각으로도 못 씁니다.

벽시계가 뒤로 가는 때

벽시계는 놔두면 조금씩 어긋납니다. 기기 안에서 시계의 박자를 만드는 부품을 수정 진동자라고 하는데, 이 부품이 온도에 따라 미세하게 빨라지고 느려지기 때문입니다. 이렇게 시계가 서서히 어긋나는 것을 클록 드리프트라고 부릅니다.

그래서 서버는 바깥의 시각에 자기 시계를 맞춥니다. 이때 쓰는 약속이 NTP(Network Time Protocol, 네트워크 시각 프로토콜)입니다. NTP 는 시각을 잘 아는 서버에 지금 몇 시인지 물어보고 그 답으로 자기 시계를 고칩니다.

고치는 방법은 두 갈래입니다. 시계가 가는 속도를 잠시 느리게 하거나 빠르게 해서 서서히 맞추는 쪽이 하나이고, 시각을 곧바로 새 값으로 바꿔 버리는 쪽이 다른 하나입니다. 뒤쪽이 벽시계가 뛰는 순간입니다. 앞선 시계를 맞추려면 값을 뒤로 돌려야 하고, 그때 벽시계는 지나온 시각을 다시 지나갑니다.

벽시계를 흔드는 것이 NTP 만은 아닙니다. 관리자가 손으로 시각을 고칠 때, 윤초 때문에 1초를 넣거나 뺄 때, 멈춰 두었던 가상 머신을 되살릴 때도 같은 일이 일어납니다.

flowchart TD
    A["일 시작 · 벽시계 10시 0분 5초 · 단조 시계 120.0"] --> B["시각 보정 · 벽시계가 10시 0분 2초로 되돌아감"]
    B --> C["일 끝 · 벽시계 10시 0분 3초 · 단조 시계 125.0"]
    C --> D["벽시계로 잰 경과 · -2초"]
    C --> E["단조 시계로 잰 경과 · 5초"]

그림의 두 갈래가 이 개념의 전부입니다. 같은 일을 재는데 벽시계는 음수를 내놓고 단조 시계는 5초를 내놓습니다. 음수가 나온 쪽이 틀린 것이 아니라, 애초에 흐른 시간을 재는 데 쓸 시계가 아니었던 것입니다.

두 번 읽어 빼는 절차

쓰는 법은 간단합니다. 일 앞뒤로 시계를 한 번씩 읽고 두 값을 뺍니다.

start   = monotonic()   // 120.000
handle_request()
end     = monotonic()   // 120.220
elapsed = end - start   // 0.220

방금 본 코드에서 120.000 과 120.220 은 아무 시각도 가리키지 않습니다. 기기가 켜진 뒤로 그만큼 지났다는 뜻일 뿐입니다. 읽는 사람에게 뜻이 있는 것은 마지막 줄의 0.220 하나입니다.

이 절차는 다른 시계로 바꿔 끼울 수 없습니다. 같은 코드를 벽시계로 쓰면 두 번 읽는 사이에 시각 보정이 한 번만 끼어들어도 elapsed 가 음수가 되거나 몇 시간으로 튑니다.

운영체제가 내주는 두 시계

응용 프로그램은 시계를 스스로 세지 않고 커널에 물어봅니다. 커널은 어느 시계를 읽을지 골라서 부르게 해 둡니다.

POSIX(Portable Operating System Interface, 이식 가능 운영체제 인터페이스)를 따르는 운영체제에서는 시계에 이름이 붙어 있고, 읽을 때 그 이름을 넘깁니다. 흐른 시간을 재는 시계가 CLOCK_MONOTONIC 이고, 달력 시각을 알려 주는 시계가 CLOCK_REALTIME 입니다. 둘 다 clock_gettime 이라는 같은 호출로 읽습니다.

언어의 표준 라이브러리도 대개 이 둘을 갈라 내줍니다. 이름은 언어마다 다르지만 고르는 기준은 같습니다.

한 가지가 더 갈립니다. 기기가 절전으로 잠든 동안 이 시계가 시간을 세느냐입니다. 잠든 시간을 빼고 세는 시계와 함께 세는 시계를 따로 내주는 운영체제가 있습니다. 노트북 뚜껑을 닫아 둔 사이에 만료되어야 할 것이 있다면 이 갈래를 확인해야 합니다.

이 시계를 고르는 기준

기준은 한 줄입니다. 두 시점 사이의 거리를 재는 것이면 단조 시계이고, 사람이나 다른 기기에 보여 줄 시각이면 벽시계입니다.

이럴 때 고를 시계
타임아웃까지 얼마나 남았는지 센다 단조 시계
지수 백오프로 다음 재시도까지 기다린다 단조 시계
속도 제한의 시간 창이 지났는지 본다 단조 시계
함수 하나가 몇 초 걸렸는지 잰다 단조 시계
잠금을 빌려 둔 기간인 리스가 남았는지 본다 단조 시계
로그 한 줄에 타임스탬프를 찍는다 벽시계
쿠폰 만료 시각을 데이터베이스에 넣는다 벽시계
두 서버의 로그를 시간순으로 맞춘다 벽시계

표의 위쪽은 전부 한 기기 안에서 벌어지고 오래 두지 않는 일입니다. 아래쪽은 값이 기기 밖으로 나가거나 다시 켠 뒤에도 남아야 하는 일입니다.

분산 시스템에서는 아래쪽마저 벽시계로 충분하지 않을 때가 있습니다. 서버마다 벽시계가 조금씩 어긋나 있어서 두 사건의 앞뒤를 시각만으로 못 가리기 때문입니다. 그럴 때는 시각 대신 순서만 매기는 논리 시계를 씁니다.

관련 항목

단조 시계와 맞세워지는 시계

벽시계 · 시스템 클록 · 실시간 시계 · 유닉스 시간 · 에포크

단조 시계를 읽는 호출과 시계 이름

clock_gettime · CLOCK_MONOTONIC · CLOCK_REALTIME · CLOCK_BOOTTIME · adjtimex · POSIX

벽시계 시각을 뒤흔드는 원인

NTP · 윤초 · 클록 드리프트 · 클록 스큐 · 수정 진동자 · 클럭 스텝 · 윤초 문지르기 · 시간대

단조 시계로 시간을 재는 처리

타임아웃 · 재시도 · 지수 백오프 · 속도 제한 · 하트비트 · 리스 · 벤치마크

기기 사이의 앞뒤를 매기는 다른 시계

논리 시계 · 벡터 시계 · 램포트 타임스탬프 · 하이브리드 논리 시계 · 스노우플레이크

시각을 기록하고 나타내는 형식

타임스탬프 · ISO 8601 · RFC 3339 · 나노초 · 로그

단조 시계를 내주는 바탕 소프트웨어

운영체제 · 커널 · 시스템 콜 · 시간과 시계 · 가상 머신

다른 이름: monotonic clock · 단조시계 · 모노토닉 클록