본문 바로가기
CS 지식/시스템 프로그래밍

[C언어] 리눅스 Time과 Clock의 종류와 POSIX Clocks

by 코딩하는 동현 2025. 3. 2.

리눅스 Time의 종류

  • Wall time (real time)
    • 실제, 절대적인 시간
  • Monotonic time
    • 선형적으로 일정하게 계속 증가하는 시간 (시스템 부팅 이후 시간)
  • Process time
    • 프로세스가 사용자 코드에서 작업을 수행하거나, 커널이 그 프로세스를 대신해서 작업하는데 걸린 시간
    • Wall time보다 적으며, 멀티태스킹 중 사용되지 않은 시간은 제외됨

Hardware Clocks

소프트웨어 클록보다 더 정확하고 빠른 하드웨어 클록

  • Real Time Clock (RTC)
    • 배터리 기반 클록
  • High Precision Event Timer (HPET)
    • 추가적인 인터럽트가 가능하여 시그널 등을 이용할 수 있음
  • Time Stamp Counter (TSC)
    • 64비트 레지스터 (x86 프로세서)
    • CPU 코어의 사이클 횟수를 측정

System (Software) Clock

  • 프로세서에서 처리하므로 오버헤드가 존재하고 정확도가 다소 떨어짐
  • 시스템 타이머의 주파수는 HZ 단위로 표현됨
    • 예: 100HZ -> 1/100s -> 10ms
  • Unix time (1970.1.1 Epoch Time) 이후 초/밀리초 단위로 표현됨 (8바이트)

Time 자료 구조

timeval (마이크로초 단위)

struct timeval{
    time_t tv_sec;       // 초 단위
    suseconds_t tv_usec; // 마이크로초 단위
};

timespec (나노초 단위)

struct timespec {
    time_t tv_sec;   // 초 단위
    long tv_nsec;    // 나노초 단위
};

tm (날짜 및 시간 표시)

struct tm* gmtime(const time_t *timep);
struct tm* localtime(const time_t *timep);

struct tm {
    int tm_sec;   // 초
    int tm_min;   // 분
    int tm_hour;  // 시
    int tm_mday;  // 일
    int tm_mon;   // 월
    int tm_year;  // 1900년 기준의 연도
    int tm_wday;  // 요일
    int tm_yday;  // 1월 1일부터 경과한 일수
    int tm_isdst; // 서머타임 여부
};

Current Time

현재 시간 가져오기

time_t time(time_t *t);

현재 시간을 time_t 형식으로 반환하고, t에 저장 (실패 시 -1 반환)

int gettimeofday(struct timeval *tv, struct timezone *tz);

현재 시간을 timeval 구조체에 저장하며, timezone 인자에는 항상 NULL을 넣음

int clock_gettime(clockid_t clock_id, struct timespec *ts);

지정한 클록의 현재 시간을 timespec 구조체에 저장


MONOTONIC 시계로 나노초 단위 측정

#include <time.h>
#include <stdio.h>
#include <stdint.h>
#define BILLION 1000000000L

int main() {
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    // 작업 수행
    clock_gettime(CLOCK_MONOTONIC, &end);
    uint64_t diff = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec;
    printf("Time: %llu nanoseconds\n", (unsigned long long)diff);
    return 0;
}

현재 시간 설정

int settime(time_t *t);

시스템 시간을 t로 설정 (루트 권한 필요)

int settimeofday(const struct timeval *tv, const struct timezone *tz);

timeval 구조체를 이용한 버전

int clock_settime(clockid_t clock_id, const struct timespec *ts);

지정한 클록의 시간을 timespec 값으로 설정

int adjtime(const struct timeval *delta, struct timeval *olddelta);
  • delta: 조정할 시간 오차
  • olddelta: 이전의 시간 오차 값을 저장하는 포인터

POSIX Clocks

POSIX(Portable Operating System Interface) 표준에서 제공하는 시스템 클록(clock) 인터페이스로, 운영체제가 다양한 시간 관련 작업을 수행할 수 있도록 지원하는 고정밀(high-resolution) 시간 측정 기능을 제공한다.
주로 clock_gettime(), clock_settime(), clock_getres() 등의 시스템 호출을 사용하여 시간을 읽거나 설정할 수 있다.

 

POSIX Clocks의 주요 특징

  1. 다양한 시간 소스를 제공
    • 단순한 실시간 시계(Wall Clock)뿐만 아니라, 프로세스별, 스레드별 CPU 시간, 시스템 부팅 이후 경과 시간 등을 측정할 수 있다.
  2. 고해상도(high-resolution) 지원
    • 마이크로초(μs) 또는 나노초(ns) 단위의 시간 정밀도를 제공한다.
    • 시스템에 따라 clock_getres()를 이용하면 특정 클록의 해상도를 확인할 수 있다.
  3. 시스템 및 애플리케이션 성능 분석에 활용
    • 실행 시간 측정, 성능 프로파일링, 시간 동기화 등에 사용된다

 

  • CLOCK_REALTIME: Wall time
  • CLOCK_MONOTONIC: 시스템이 시작된 이후 경과된 시간, 시스템 시간이 변경되더라도 영향 없음
  • CLOCK_PROCESS_CPUTIME_ID: 프로세스별 CPU 사용 시간 측정
  • CLOCK_THREAD_CPUTIME_ID: 개별 스레드의 CPU 사용 시간 측정

Time Source Resolution

int clock_getres(clockid_t clock_id, struct timespec *res);

시계의 해상도를 가져오는 함수

해상도 구하기 예제

#include <time.h>
#include <stdio.h>

int main() {
    clockid_t clocks[] = {
        CLOCK_REALTIME,
        CLOCK_MONOTONIC,
        CLOCK_PROCESS_CPUTIME_ID,
        CLOCK_THREAD_CPUTIME_ID,
        (clockid_t)-1
    };
    struct timespec res;
    for (int i = 0; clocks[i] != (clockid_t)-1; i++) {
        if (clock_getres(clocks[i], &res)) {
            perror("clock_getres");
        } else {
            printf("clock id=%d sec=%ld nsec=%ld\n", clocks[i], res.tv_sec, res.tv_nsec);
        }
    }
    return 0;
}
반응형

댓글