학습자료(~2017)/리눅스

[리눅스] 시간 관련 함수, 자료 정리

단세포소년 2012. 3. 7. 17:53
반응형

Unix / Linux에는 다양한 형태의 시간 타입이 정의 되어 있습니다. 각 타입마다 용도도 다르고 그 표현 가능한 단위도 조금조금씩 달라서 헷갈릴 때가 많아 정리해보았습니다.

POSIX 기본 (POSIX:CX)

time_t
long 타입으로 선언되어 있으며 초단위의 시간세밀도를 지원합니다.

#include <time.h>
time_t time(time_t *t)

Epoch 이후의 시간을 t에도 담아주고 반환도 해줍니다. t가 NULL이라면 반환만 합니다
Ephoch란 1970년 1월 1일 00:00 자정으로 정의되어 있으며, 이를 UTC 또는 GMT라고도 부릅니다.

이 시간 타입을 사용하는 함수들입니다.
#include <time.h>
double difftime(time_t time1, time_t time0);

두 시간의 차를 double 타입으로 반환합니다. 왜 double 타입으로 반환하는지는 모르겠네요.  

#include <time.h>
char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);

time_t 형이 가리키는 시간을 문자열로 변환하여 반환합니다. ctime()은 문자열 끝에 개행문자를 채워서 반환하기 때문에 출력할 때 굳이 '\n'을 붙이지 않아도 됩니다. 그리고 애석하게도 쓰레드 안전성을 보장하지 않기 때문에 멀티 쓰레드 프로그래밍에서는 ctime_r()을 사용하도록 합니다.

반환되는 문자열 예:
  Mon Feb 23 23:55:34 2009


struct tm
이 시간 구조체의 멤버들은 다음과 같습니다

struct tm {
    int tm_sec;   // 분(minute) 후의 초(second) [0, 60]
    int tm_min;   // 시(hour) 후의 분(minute) [0, 59]
    int tm_hour;  // 자정 이후의 시(hour) [0, 23]
    int tm_mday;  // 달(month)중의 날(day) [1, 31]
    int tm_mon;   // 1월 이후부터의 달(month) [0, 11] <- 조심할 것, 1월은 0이고 12월은 11이다.
    int tm_year;  // 1900이후의 년도 <- 1900년은 0이다. 1901년은 1이고
    int tm_wday;  // 일요일부터의 요일 [0, 6] <- 일요일 0부터 토요일 6까지 이다.
    int tm_yday;  // 1월 1일 이후부터의 날 [0, 365] <- 1월 1일은 0이다. 1월 2일은 1이다. 2월 1일은 31이다.
    int tm_isdst; // 일광 절약 시간을 나타내는 플래그
};

tm_sec가 왜 60까지일까요? 곰곰히 생각해봤는데 우리가 사용하는 시간이 지구의 공전 주기와 정확히 일치하지 않기 때문에 몇년인지는 기억은 잘 안나지만 하여튼 몇년에 한번씩 12월 31일 23:59:59 다음에 23:59:60초를 넣습니다. 그 다음에 1월 1일 00:00:00초가 되는 거구요. 그렇기 때문에 tm_min은 59분까지인 반면 tm_sec는 60초까지 설정이 가능한겁니다.
tm_yday가 365까지 인 이유도 4년에 한번씩 2월이 29일까지 있기 때문입니다.

이 시간 타입을 사용하는 함수들입니다.
#include <time.h>
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
struct tm *gmtime(const time_t *timep);
struct tm *gmtime(const time_t *timep, struct tm *result);

localtime()과 gmtime()은 time_t 타입의 시간을 struct tm 타입에 맞게 변환하고 그 포인터를 반환합니다. localtime()은 지역적 특성(타임존, 일광 절약 시간 등)에 따라 조정한 후 반환합니다. 쓰레드 안전성을 위해 멀티 쓰레드 프로그래밍에는 localtime_r()과 gmtime_r()을 사용합니다

#include <time.h>
char *asctime(const struct tm *timep);
char *asctime_r(const struct tm *timeptr, char *buf);

asctime()은 struct tm 타입을 인자로 받는다는 것을 제외하고는 ctime()과 완전히 동일합니다. 역시 쓰레드 안전성을 원한다면 asctime_r()을 사용하도록 합니다.


clock_t
time()은 elapsed time 혹은 wall-clock라고 불리는 실제 시간을 측정합니다. 그러므로 실제 프로세스가 사용한 시간을 이 함수로 측정할 수 없습니다. 프로세스가 실행 상태로 있는 동안 사용한 시간을 가상 시간(virtual time)이라고 부흐며 이는 times() 함수로 얻어 올 수 있습니다

clock_t 타입은 클록 틱(tick) 단위인데 일반적으로 초(second)와 틱(tick)의 관계는 1초당 100틱입니다. 현재 사용중인 시스템의 틱은 sysconf(_SC_CLK_TCK)을 통해 얻어 올 수 있습니다. clock_t 값을 틱으로 나누면 초(second)를 얻을 수 있습니다.

struct tms
times() 함수가 반환하는 가상시간을 나타내기 위한 구조체입니다. 구조체 멤버는 다음과 같습니다.

struct tms {
    clock_t tms_utime; // user time
    clock_t tms_stime; // system time
    clock_t tms_cutime; // user time of children
    clock_t tms_cstime; // system time of children
};

이 시간 타입을 사용하는 함수들입니다.
#include <sys/time.h>
clock_t times(struct tms *buf);

반환 값은 시스템이나 프로세스가 시작된 시점 등과 같은 임의의 시점부터 결과된 시간을 clock_t 타입의 값으로 반환합니다. 실패하면 -1을 반환하고 errno를 설정합니다. buf에 프로세스가 사용한 시간정보를 담아줍니다.



POSIX Extension (POSIX:XSI)

struct timeval
마이크로초 (1/1,000,000) 까지 측정이 가능합니다. 구조체 멤버는 다음과 같습니다.

struct timeval {
    time_t tv_sec;  // Epochi 이후부터의 초 단위 시간
    time_t tv_usec; // 그리고 마이크로초(microseconds)
};

#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);

gettimeofday()는 Epoch 이후의 시간을 초와 마이크로초단위로 얻어옵니다. tz는 사용되지 않으며 NULL을 넘겨 주면 됩니다.


 
POSIX Timers Extention (POSIX:TMR)

clockid_t
클록(clock)은 클록 세밀도(clock resolution)이라 불리는 고정된 짧은 시간 마다 증가되는 카운터입니다. 이 클록의 타입은 clockid_t 타입니다. 시스템 전역에 사용되는 실시간 클록으로 CLOCK_REALTIME이 있고, 또는 프로세스에서 사용되는 실시간 클록으로 CLOCK_PROCESS_CPU_TIME이 있습니다. 보통 클록은 gettimeofday()함수보다 높은 세밀도를 제공합니다. 이 clock_id 타입 값을 clock_gettime()를 통해 struct timespec 구조체로 변환 할 수 있습니다.

struct timespec
나노초 (1/1,000,000,000) 까지 측정이 가능합니다. 구조체 멤버는 다음과 같습니다.

struct timespec {
    time_t tv_sec; // 초 (seconds)
    long tv_nsec;  // 나노초 (nanoseconds)
}

이 시간 타입을 사용하는 함수들입니다.
#include <sys/time.h>
int clock_gettime(clockid_t which_clock, struct timespec *tp);

clock_id 타입인 which_clock을 struct timespec 구조체 타입으로 변환해줍니다.

#include <sys/time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);

sleep()은 초단위로 밖에 설정할 수가 없습니다. 그래서 좀더 세밀하게 프로세스를 블록시키기 위해서는 nanosleep()을 사용합니다. nanosleep()은 req에 지정된 시간만큼 또는 시그널을 받을 때까지 쓰레드를 블록시킵니다. 만약 시그널에 의해 쓰레드가 깨어나고 rem이 NULL이 아니라면 rem에 남은 시간을 담아줍니다.


출처 : http://blog.yongil.net/78



시간 단위

 마이크로 초 (μs로 표기)는 백만 분의 1초, 즉 10-6초를 가리킨다.

다른 단위들과 비교를 하자면, 밀리 초 (ms 또는 msec으로 표기)는 천 분의 1초로서, 대개 하드디스크CD-ROM 플레이어의 액세스 속도나, 인터넷상에서 패킷이 움직이는 속도를 측정하는데 사용된다.

나노 초 (ns로 표기)는 십억 분의 1초, 즉 10-9초를 가리키며, 보통 RAM액세스 속도를 측정하는 단위로 사용된다.

피코 초 (ps로 표기)는 10-12초, 또는 백만 분의 1 마이크로 초이다.

펨토 초 (fs로 표기)는 10-15초로서 레이저 기술에서 종종 사용되는 단위이다.

애토 초는 10-18초로서 광자 연구에서 사용되는 용어이다.


출처 : http://www.google.co.kr/url?url=http://terms.co.kr/microsecond.htm&rct=j&sa=X&ei=YSFXT565A9GfmQXi8NizDw&ved=0CDMQ2xEoADAA&q=%EB%A7%88%EC%9D%B4%ED%81%AC%EB%A1%9C%EC%B4%88&usg=AFQjCNG02oaidxmyTcM5gZ1aPkuggnL-kA&cad=rjt

반응형