Skip to content

clock_nanosleep(2)

Seonghun Lim edited this page Jan 31, 2019 · 1 revision

NAME

clock_nanosleep - 클럭 지정이 가능한 고해상도 sleep

SYNOPSIS

#include <time.h>

int clock_nanosleep(clockid_t clock_id, int flags,
                    const struct timespec *request,
                    struct timespec *remain);

-lrt로 링크 (glibc 버전 2.17 전에서만).

glibc 기능 확인 매크로 요건 (feature_test_macros(7) 참고):

clock_nanosleep()
_POSIX_C_SOURCE >= 200112L

DESCRIPTION

nanosleep(2)과 마찬가지로 clock_nanosleep()을 통해 호출 스레드가 나노초 정밀도로 지정한 시간 동안 잠들 수 있다. 차이점은 수면 시간을 측정하는 클럭을 호출자가 선택할 수 있다는 점과 수면 시간을 절댓값이나 상댓값으로 지정할 수 있다는 점이다.

이 호출로 주거나 돌려받는 시간 값들은 다음과 같이 정의된 timespec 구조체로 나타낸다.

struct timespec {
    time_t   tv_sec;        /* 초 */
    long     tv_nsec;       /* 나노초 ([0 .. 999999999] */
};

clock_id 인자는 잠드는 시간을 측정할 클럭을 나타낸다. 다음 값들 중 하나를 이 인자에 쓸 수 있다.

CLOCK_REALTIME
설정 가능한 시스템 전역 실제 시간 클럭.
CLOCK_MONOTONIC
시스템 시동 후 바뀌지 않는 과거 어떤 불특정 시점부터의 시간을 측정하는 설정 불가능한 단조 증가 클럭.
CLOCK_PROCESS_CPUTIME_ID (리눅스 2.6.12부터.)
프로세스의 모든 스레드가 소모한 CPU 시간을 측정하는 설정 가능한 프로세스별 클럭.

이 클럭들에 대한 더 자세한 내용은 clock_getres(2)를 보라. 또한 clock_getcpuclockid(3)pthread_getcpuclockid(3)가 반환한 CPU 클럭 ID도 clock_id에 줄 수 있다.

flags가 0이면 request에 지정한 값을 clock_id에 지정한 클럭의 현재 값에 대한 상대적 시간으로 해석한다.

flagsTIMER_ABSTIME이면 requestclock_id 클럭으로 측정한 절대 시간으로 해석한다. request가 클럭의 현재 값보다 작거나 값으면 호출 스레드가 멈추지 않고 clock_nanosleep()이 즉시 반환한다.

clock_nanosleep()은 적어도 request에 지정한 시간이 지날 때까지, 또는 핸들러 호출을 유발하거나 프로세스를 종료시키는 시그널이 전달될 때까지 호출 스레드의 실행을 멈춘다.

호출이 시그널 핸들러에 의해 중단되는 경우에는 clock_nanosleep()EINTR 오류로 실패한다. 더불어 remain이 NULL이 아니고 flagsTIMER_ABSTIME이 아니었으면 남은 수면 시간을 remain으로 반환한다. 그러면 이 값으로 다시 clock_nanosleep()을 호출해서 (상대적) 수면을 끝마칠 수 있다.

RETURN VALUE

요청 시간 동안 성공적으로 잠든 경우 clock_nanosleep()은 0을 반환한다. 호출이 시그널 핸들러에 의해 중단되거나 오류를 만난 경우에는 ERRORS에 나열된 양수 오류 번호들 중 하나를 반환한다.

ERRORS

EFAULT
지정한 requestremain이 유효하지 않은 주소이다.
EINTR
시그널 핸들러에 의해 잠들기가 중단되었다. signal(7) 참고.
EINVAL
tv_nsec 필드의 값이 0에서 999999999까지 범위 안이 아니거나 tv_sec이 음수이다.
EINVAL
clock_id가 유효하지 않다. (CLOCK_THREAD_CPUTIME_IDclock_id에 가능한 값이 아니다.)

VERSIONS

리눅스 2.6에서 clock_nanosleep() 시스템 호출이 처음 등장했다. glibc 버전 2.1부터 지원을 쓸 수 있다.

CONFORMING TO

POSIX.1-2001, POSIX.1-2008.

NOTES

request에 지정한 시간이 기반 클럭 정밀도(time(7) 참고)의 정수배가 아니면 다음 배수로 시간을 올림 한다. 또한 잠들기가 끝난 후에도 CPU에서 호출 스레드를 다시 실행할 수 있게 될 때까지 지연이 있을 수도 있다.

절대 타이머를 쓰면 nanosleep(2)에서 설명하는 늦춰지는 문제를 막는 데 도움이 된다. (상대적 잠들기가 반복적으로 시그널에 의해 중단돼서 재시작하려 하는 프로그램에서 그 문제가 심해진다.) 상대적 잠들기를 하면서 이 문제를 피하려면 원하는 클럭으로 clock_gettime(2)을 호출하고서 TIMER_ABSTIME 플래그로 clock_nanosleep()을 호출하면 된다.

clock_nanosleep()sigaction(2) SA_RESTART 플래그를 쓰더라도 시그널 핸들러에 의해 중단된 후 절대 재시작되지 않는다.

flagsTIMER_ABSTIME일 때는 remain 인자를 안 쓰며 필요도 없다. (절대 시간 잠들기는 같은 request 인자를 써서 재시작할 수 있다.)

POSIX.1에서는 clock_nanosleep()이 시그널 처리 방식이나 시그널 마스크에 어떤 영향도 끼치지 않는다고 명세한다.

POSIX.1에서는 clock_settime(2)을 통해 CLOCK_REALTIME의 값을 바꾼 후에는 절대적 clock_nanosleep()에 블록 된 스레드가 깨어날 시점을 새 클럭 값으로 정해야 한다고 명세하고 있다. 새 클럭 값이 수면 시간 끝을 넘어간다면 clock_nanosleep() 호출이 즉시 반환된다.

POSIX.1에서는 clock_settime(2)을 통해 CLOCK_REALTIME의 값을 바꾸는 것이 상대적 clock_nanosleep()에 블록 된 스레드에 어떤 영향도 끼치지 않아야 한다고 명세하고 있다.

SEE ALSO

clock_getres(2), nanosleep(2), restart_syscall(2), timer_create(2), sleep(3), usleep(3), time(7)


2017-09-15

Clone this wiki locally