timerfd_create(2) - wariua/manpages-ko GitHub Wiki

NAME

timerfd_create, timerfd_settime, timerfd_gettime - 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό 톡해 μ•Œλ € μ£ΌλŠ” 타이머

SYNOPSIS

#include <sys/timerfd.h>

int timerfd_create(int clockid, int flags);

int timerfd_settime(int fd, int flags,
                    const struct itimerspec *new_value,
                    struct itimerspec *old_value);

int timerfd_gettime(int fd, struct itimerspec *curr_value);

DESCRIPTION

이 μ‹œμŠ€ν…œ ν˜ΈμΆœλ“€μ€ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό 톡해 타이머 만료 μ•Œλ¦Όμ„ μ „λ‹¬ν•˜λŠ” 타이머λ₯Ό μƒμ„±ν•˜κ³  μ‘°μž‘ν•œλ‹€. setitimer(2)λ‚˜ timer_create(2)의 λŒ€μ•ˆμ΄ λ˜μ–΄ μ£ΌλŠ”λ° select(2), poll(2), epoll(7)둜 κ·Έ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό κ°μ‹œν•  수 μžˆλ‹€λŠ” μž₯점이 μžˆλ‹€.

이 μ„Έ κ°€μ§€ μ‹œμŠ€ν…œ 호좜 μ‚¬μš©λ²•μ€ timer_create(2), timer_settime(2), timer_gettime(2)κ³Ό λΉ„μŠ·ν•˜λ‹€. (timer_getoverrun(2)에 λŒ€μ‘ν•˜λŠ” 것은 μ—†λ‹€. μ•„λž˜μ—μ„œ μ„€λͺ…ν•˜λ“― read(2)둜 κ·Έ κΈ°λŠ₯성을 μ œκ³΅ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.)

timerfd_create()

timerfd_create()λŠ” μƒˆ 타이머 객체λ₯Ό μƒμ„±ν•˜κ³  κ·Έ 타이머λ₯Ό κ°€λ¦¬ν‚€λŠ” 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λ°˜ν™˜ν•œλ‹€. clockid μΈμžλŠ” 타이머 진행을 νŠΉμ§• μ§“λŠ” ν΄λŸ­μ„ λ‚˜νƒ€λ‚΄λ©° λ‹€μŒ 쀑 ν•œ κ°€μ§€μ—¬μ•Ό ν•œλ‹€.

CLOCK_REALTIME
μ„€μ • κ°€λŠ₯ν•˜λ©° μ‹œμŠ€ν…œ 전역인 μ‹€μ œ μ‹œκ°„ 클럭.
CLOCK_MONOTONIC
μ„€μ • λΆˆκ°€λŠ₯ν•˜λ©° μ‹œμŠ€ν…œ ꡬ동 ν›„ λ°”λ€Œμ§€ μ•ŠλŠ” κ³Όκ±° λΆˆνŠΉμ • μ‹œμ μœΌλ‘œλΆ€ν„°μ˜ μ‹œκ°„μ„ μΈ‘μ •ν•˜λŠ” 단쑰 증가 클럭.
CLOCK_BOOTTIME (λ¦¬λˆ…μŠ€ 3.15λΆ€ν„°)
CLOCK_MONOTONIC처럼 단쑰 μ¦κ°€ν•˜λŠ” ν΄λŸ­μ΄λ‹€. ν•˜μ§€λ§Œ CLOCK_MONOTONIC ν΄λŸ­μ—μ„œ μ‹œμŠ€ν…œμ΄ μ ˆμ „ λŒ€κΈ° μƒνƒœμΈ μ‹œκ°„μ„ μΈ‘μ •ν•˜μ§€ μ•ŠλŠ” 반면 CLOCK_BOOTTIME ν΄λŸ­μ—μ„œλŠ” μ‹œμŠ€ν…œμ΄ μ ˆμ „ λŒ€κΈ° μƒνƒœμΈ μ‹œκ°„μ„ ν¬ν•¨ν•œλ‹€. μ ˆμ „ λŒ€κΈ°λ₯Ό 인식할 ν•„μš”κ°€ μžˆλŠ” μ‘μš©λ“€μ— μœ μš©ν•˜λ‹€. 그런 μ‘μš©λ“€μ— CLOCK_REALTIME은 μ ν•©ν•˜μ§€ μ•Šμ€λ°, κ·Έ ν΄λŸ­μ€ μ‹œμŠ€ν…œ 클럭의 λΆˆμ—°μ†μ  변화에 영ν–₯을 λ°›κΈ° λ•Œλ¬Έμ΄λ‹€.
CLOCK_REALTIME_ALARM (λ¦¬λˆ…μŠ€ 3.11λΆ€ν„°)
이 ν΄λŸ­μ€ CLOCK_REALTIMEκ³Ό λΉ„μŠ·ν•˜λ˜ μ‹œμŠ€ν…œμ΄ μ ˆμ „ λŒ€κΈ° μƒνƒœμ΄λ©΄ 깨우게 λœλ‹€. 이 ν΄λŸ­μ— λŒ€ν•΄ 타이머λ₯Ό μ„€μ •ν•˜κΈ° μœ„ν•΄μ„  ν˜ΈμΆœμžκ°€ CAP_WAKE_ALARM μ—­λŠ₯을 κ°€μ§€κ³  μžˆμ–΄μ•Ό ν•œλ‹€.
CLOCK_BOOTTIME_ALARM (λ¦¬λˆ…μŠ€ 3.11λΆ€ν„°)
이 ν΄λŸ­μ€ CLOCK_BOOTTIMEκ³Ό λΉ„μŠ·ν•˜λ˜ μ‹œμŠ€ν…œμ΄ μ ˆμ „ λŒ€κΈ° μƒνƒœμ΄λ©΄ 깨우게 λœλ‹€. 이 ν΄λŸ­μ— λŒ€ν•΄ 타이머λ₯Ό μ„€μ •ν•˜κΈ° μœ„ν•΄μ„  ν˜ΈμΆœμžκ°€ CAP_WAKE_ALARM μ—­λŠ₯을 κ°€μ§€κ³  μžˆμ–΄μ•Ό ν•œλ‹€.

이 ν΄λŸ­λ“€ 각각의 ν˜„μž¬ 값은 clock_gettime(2)을 μ΄μš©ν•΄ μ–»μ–΄ 올 수 μžˆλ‹€.

λ¦¬λˆ…μŠ€ 2.6.27λΆ€ν„° flags에 λ‹€μŒ 값듀을 λΉ„νŠΈ OR ν•΄μ„œ timerfd_create()의 λ™μž‘ 방식을 λ°”κΏ€ 수 μžˆλ‹€.

TFD_NONBLOCK
μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ κ°€λ¦¬ν‚€λŠ” μ—΄λ¦° 파일 기술 ν•­λͺ©(open(2) μ°Έκ³ )에 O_NONBLOCK 파일 μƒνƒœ ν”Œλž˜κ·Έλ₯Ό μ„€μ •ν•œλ‹€. 이 ν”Œλž˜κ·Έλ₯Ό μ‚¬μš©ν•˜λ©΄ 같은 κ²°κ³Όλ₯Ό μ–»κΈ° μœ„ν•΄ fcntl(2)을 μΆ”κ°€λ‘œ ν˜ΈμΆœν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.
TFD_CLOEXEC
μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°μ— 'execμ—μ„œ λ‹«κΈ°'(FD_CLOEXEC) ν”Œλž˜κ·Έλ₯Ό μ„€μ •ν•œλ‹€. 이게 μœ μš©ν•  수 μžˆλŠ” μ΄μœ μ— λŒ€ν•΄μ„  open(2)의 O_CLOEXEC ν”Œλž˜κ·Έ μ„€λͺ…을 보라.

λ¦¬λˆ…μŠ€ 버전 2.6.26κΉŒμ§€μ—μ„œλŠ” flagsλ₯Ό 0으둜 μ§€μ •ν•΄μ•Ό ν•œλ‹€.

timerfd_settime()

timerfd_settime()은 파일 λ””μŠ€ν¬λ¦½ν„° fdκ°€ κ°€λ¦¬ν‚€λŠ” 타이머λ₯Ό μž₯μ „(μ‹œμž‘)ν•˜κ±°λ‚˜ ν•΄μ œ(μ •μ§€)ν•œλ‹€.

new_value μΈμžλŠ” νƒ€μ΄λ¨Έμ˜ 졜초 만료 μ‹œκ°„κ³Ό 간격을 μ§€μ •ν•œλ‹€. 이 μΈμžμ— μ“°λŠ” itimerspec κ΅¬μ‘°μ²΄μ—λŠ” 두 ν•„λ“œκ°€ 있고 각각이 λ‹€μ‹œ timespec νƒ€μž… ꡬ쑰체이닀.

struct timespec {
    time_t tv_sec;                /* 초 */
    long   tv_nsec;               /* λ‚˜λ…Έμ΄ˆ */
};

struct itimerspec {
    struct timespec it_interval;  /* μ£ΌκΈ° νƒ€μ΄λ¨Έμ˜ 간격 */
    struct timespec it_value;     /* 졜초 만료 */
};

new_value.it_valueλŠ” νƒ€μ΄λ¨Έμ˜ 졜초 만료 μ‹œκ°„μ„ μ΄ˆμ™€ λ‚˜λ…Έμ΄ˆλ‘œ μ§€μ •ν•œλ‹€. new_value.it_value의 ν•œ ν•„λ“œλΌλ„ 0 μ•„λ‹Œ κ°’μœΌλ‘œ μ„€μ •ν•˜λ©΄ 타이머가 μž₯μ „λœλ‹€. new_value.it_value의 두 ν•„λ“œλ₯Ό λͺ¨λ‘ 0으둜 μ„€μ •ν•˜λ©΄ 타이머λ₯Ό ν•΄μ œν•œλ‹€.

new_value.it_interval의 ν•„λ“œ ν•œ κ°œλ‚˜ 두 개λ₯Ό 0 μ•„λ‹Œ κ°’μœΌλ‘œ μ„€μ •ν•˜λ©΄ 졜초 만료 ν›„ νƒ€μ΄λ¨Έμ˜ 반볡 만료 μ£ΌκΈ°λ₯Ό μ΄ˆμ™€ λ‚˜λ…Έμ΄ˆλ‘œ μ§€μ •ν•œλ‹€. new_value.it_interval의 두 ν•„λ“œκ°€ λͺ¨λ‘ 0이면 new_value.it_value둜 μ§€μ •ν•œ μ‹œκ°„μ— ν•œ 번만 타이머가 λ§Œλ£Œλœλ‹€.

기본적으둜 new_value둜 μ§€μ •ν•˜λŠ” 졜초 만료 μ‹œκ°„μ€ 호좜 μ‹œμ μ— 타이머 클럭의 ν˜„μž¬ μ‹œκ°„μ„ κΈ°μ€€μœΌλ‘œ μƒλŒ€μ μœΌλ‘œ ν•΄μ„ν•œλ‹€. (즉, new_value.it_valueκ°€ μ§€μ •ν•˜λŠ” 것이 clockid둜 μ§€μ •ν•œ 클럭의 ν˜„μž¬ 값에 λŒ€ν•œ μƒλŒ€μ  μ‹œκ°„μ΄λ‹€.) flags 인자λ₯Ό 톡해 μ ˆλŒ€ μ‹œκ°„ νƒ€μž„μ•„μ›ƒμ„ 선택할 수 μžˆλ‹€.

flags μΈμžλŠ” λΉ„νŠΈ 마슀크이며 λ‹€μŒ 같듀을 포함할 수 μžˆλ‹€.

TFD_TIMER_ABSTIME
new_value.it_valueλ₯Ό 타이머 ν΄λŸ­μ—μ„œμ˜ μ ˆλŒ“κ°’μœΌλ‘œ ν•΄μ„ν•œλ‹€. νƒ€μ΄λ¨Έμ˜ 클럭이 new_value.it_value둜 μ§€μ •ν•œ 값에 도달할 λ•Œ 타이머가 λ§Œλ£Œλœλ‹€.
TFD_TIMER_CANCEL_ON_SET
TFD_TIMER_ABSTIMEκ³Ό ν•¨κ»˜ 이 ν”Œλž˜κ·Έλ₯Ό μ§€μ •ν•˜κ³  이 νƒ€μ΄λ¨Έμ˜ 클럭이 CLOCK_REALTIMEμ΄λ‚˜ CLOCK_REALTIME_ALARM이면 μ‹€μ œ μ‹œκ°„ 클럭이 λΆˆμ—°μ†μ  λ³€κ²½(settimeofday(2)λ‚˜ clock_settime(2) 같은 것)을 κ²ͺ을 λ•Œ 이 타이머λ₯Ό μ·¨μ†Œν•  수 μžˆλ‹€κ³  ν‘œμ‹œν•œλ‹€. 그런 변경이 일어날 λ•Œ 파일 λ””μŠ€ν¬λ¦½ν„°μ— λŒ€ν•œ ν˜„μž¬λ‚˜ 미래의 read(2)κ°€ ECANCELED 였λ₯˜λ‘œ μ‹€νŒ¨ν•˜κ²Œ λœλ‹€.

old_value μΈμžκ°€ NULL이 μ•„λ‹ˆλ©΄ κ°€λ¦¬ν‚€λŠ” itimerspec ꡬ쑰체λ₯Ό μ΄μš©ν•΄ 호좜 μ‹œμ μ— 적용 μ€‘μ΄λ˜ 타이머 섀정을 λ°˜ν™˜ν•œλ‹€. μ΄μ–΄μ§€λŠ” timerfd_gettime() μ„€λͺ…을 μ°Έκ³ ν•˜λΌ.

timerfd_gettime()

timerfd_gettime()은 파일 λ””μŠ€ν¬λ¦½ν„° fdκ°€ κ°€λ¦¬ν‚€λŠ” νƒ€μ΄λ¨Έμ˜ ν˜„μž¬ 섀정을 담은 itimerspec ꡬ쑰체λ₯Ό curr_value둜 λ°˜ν™˜ν•œλ‹€.

it_value ν•„λ“œλŠ” 타이머가 λ‹€μŒ 만료될 λ•ŒκΉŒμ§€ 남은 μ‹œκ°„μ„ λ°˜ν™˜ν•œλ‹€. 이 ꡬ쑰체의 두 ν•„λ“œκ°€ λͺ¨λ‘ 0이라면 타이머가 ν˜„μž¬ ν•΄μ œλ˜μ–΄ μžˆλŠ” 것이닀. 타이머λ₯Ό μ„€μ •ν•  λ•Œ TFD_TIMER_ABSTIME ν”Œλž˜κ·Έλ₯Ό μ§€μ •ν–ˆλŠ”μ§€μ™€ λ¬΄κ΄€ν•˜κ²Œ 이 ν•„λ“œλŠ” 항상 μƒλŒ“κ°’μ„ λ‹΄κ³  μžˆλ‹€.

it_interval ν•„λ“œλŠ” νƒ€μ΄λ¨Έμ˜ 간격을 λ°˜ν™˜ν•œλ‹€. 이 ꡬ쑰체의 두 ν•„λ“œκ°€ λͺ¨λ‘ 0이라면 curr_value.it_value둜 μ§€μ •ν•œ μ‹œκ°„μ— ν•œ 번만 λ§Œλ£Œλ˜λ„λ‘ 타이머가 μ„€μ •λ˜μ–΄ μžˆλŠ” 것이닀.

타이머 파일 λ””μŠ€ν¬λ¦½ν„° μ‘°μž‘

timerfd_create()κ°€ λ°˜ν™˜ν•˜λŠ” 파일 λ””μŠ€ν¬λ¦½ν„°λŠ” λ‹€μŒ μž‘μ—…μ„ μ§€μ›ν•œλ‹€.

read(2)

timerfd_settime()을 μ΄μš©ν•΄ λ§ˆμ§€λ§‰μœΌλ‘œ 섀정을 λ³€κ²½ν•œ μ΄ν›„λ‘œ, λ˜λŠ” λ§ˆμ§€λ§‰ read(2) 성곡 μ΄ν›„λ‘œ 타이머가 ν•œ 번 이상 λ§Œλ£Œλ˜μ—ˆμœΌλ©΄ λ°œμƒν•œ 만료 횟수λ₯Ό 담은 λΆ€ν˜Έ μ—†λŠ” 8λ°”μ΄νŠΈ μ •μˆ˜(uint64_t)λ₯Ό read(2)에 μ€€ λ²„νΌλ‘œ λ°˜ν™˜ν•œλ‹€. (λ°˜ν™˜λ˜λŠ” 값은 호슀트 λ°”μ΄νŠΈ μˆœμ„œ, 즉 호슀트 λ¨Έμ‹  자체의 μ •μˆ˜ λ°”μ΄νŠΈ μˆœμ„œλ‘œ λ˜μ–΄ μžˆλ‹€.)

read(2) μ‹œμ κΉŒμ§€ 타이머 λ§Œλ£Œκ°€ λ°œμƒν•˜μ§€ μ•Šμ•˜μœΌλ©΄ λ‹€μŒ 타이머 λ§Œλ£ŒκΉŒμ§€ 호좜이 블둝 ν•œλ‹€. λ˜λŠ” (fcntl(2) F_SETFL λ™μž‘μœΌλ‘œ O_NONBLOCK ν”Œλž˜κ·Έλ₯Ό μ„€μ •ν•΄μ„œ) 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λΉ„λΈ”λ‘œν‚ΉμœΌλ‘œ λ§Œλ“€μ—ˆλ‹€λ©΄ EAGAIN 였λ₯˜λ‘œ μ‹€νŒ¨ν•œλ‹€.

μ œκ³΅ν•œ λ²„νΌμ˜ 크기가 8λ°”μ΄νŠΈλ³΄λ‹€ μž‘μœΌλ©΄ read(2)κ°€ EINVAL 였λ₯˜λ‘œ μ‹€νŒ¨ν•œλ‹€.

μ—°κ³„λœ 클럭이 CLOCK_REALTIMEμ΄λ‚˜ CLOCK_REALTIME_ALARM이고, 타이머가 μ ˆλŒ€μ΄κ³  (TFD_TIMER_ABSTIME), timerfd_settime() 호좜 λ•Œ TFD_TIMER_CANCEL_ON_SET ν”Œλž˜κ·Έλ₯Ό μ§€μ •ν–ˆλ‹€λ©΄ μ‹€μ œ μ‹œκ°„ 클럭이 λΆˆμ—°μ†μ  변경을 κ±°μΉ˜λŠ” 경우 read(2)κ°€ ECANCELED 였λ₯˜λ‘œ μ‹€νŒ¨ν•œλ‹€. (이λ₯Ό 톡해 읽기λ₯Ό ν•˜λŠ” μ‘μš©μ—μ„œ ν΄λŸ­μ— λΆˆμ—°μ†μ  변경이 μΌμ–΄λ‚¬μŒμ„ μ•Œμ•„μ±Œ 수 μžˆλ‹€.)

poll(2), select(2) (기타 μœ μ‚¬ ν•¨μˆ˜)

타이머 λ§Œλ£Œκ°€ ν•œ 번 이상 일어났을 λ•Œ 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ 읽기 κ°€λŠ₯ν•˜λ‹€. (select(2) readfds 인자, poll(2) POLLIN ν”Œλž˜κ·Έ.)

파일 λ””μŠ€ν¬λ¦½ν„°κ°€ pselect(2), ppoll(2), epoll(7) 같은 λ‹€λ₯Έ 파일 λ””μŠ€ν¬λ¦½ν„° 닀쀑화 API도 μ§€μ›ν•œλ‹€.

ioctl(2)

λ‹€μŒμ˜ timerfd ν•œμ • λͺ…령을 μ§€μ›ν•œλ‹€.

TFD_IOC_SET_TICKS (λ¦¬λˆ…μŠ€ 3.17λΆ€ν„°)
λ°œμƒν•œ 타이머 만료 횟수λ₯Ό μ‘°μ •ν•œλ‹€. μΈμžλŠ” μƒˆ 만료 횟수λ₯Ό 담은 0 μ•„λ‹Œ 8λ°”μ΄νŠΈ μ •μˆ˜μ— λŒ€ν•œ 포인터(uint64_t*)이닀. 횟수λ₯Ό μ„€μ •ν•˜κ³  λ‚˜μ„œ κ·Έ 타이머에 λŒ€κΈ° 쀑인 ν”„λ‘œμ„ΈμŠ€κ°€ 있으면 λͺ¨λ‘ κΉ¨μš΄λ‹€. 이 λͺ…λ Ήμ˜ μœ μΌν•œ μš©λ„λŠ” 체크포인트/볡원 λͺ©μ μœΌλ‘œ 만료 횟수λ₯Ό λ³΅μ›ν•˜λŠ” 것이닀. 컀널을 CONFIG_CHECKPOINT_RESTORE μ˜΅μ…˜μœΌλ‘œ κ΅¬μ„±ν•œ κ²½μš°μ—λ§Œ 이 λ™μž‘μ΄ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.
close(2)
파일 λ””μŠ€ν¬λ¦½ν„°κ°€ 더 이상 ν•„μš”ν•˜μ§€ μ•ŠμœΌλ©΄ λ‹«μ•„μ•Ό ν•œλ‹€. 동일 타이머 객체에 μ—°κ³„λœ λͺ¨λ“  파일 λ””μŠ€ν¬λ¦½ν„°κ°€ λ‹«ν˜”μ„ λ•Œ 컀널이 타이머λ₯Ό ν•΄μ œν•˜κ³  κ·Έ μžμ›μ„ ν•΄μ œν•œλ‹€.

fork(2) λ™μž‘ 방식

timerfd_create()으둜 μƒμ„±ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°μ˜ 사본을 fork(2) 후에 μžμ‹μ΄ λ¬Όλ €λ°›λŠ”λ‹€. κ·Έ 파일 λ””μŠ€ν¬λ¦½ν„°λŠ” λΆ€λͺ¨μ—μ„œμ˜ λŒ€μ‘ν•˜λŠ” 파일 λ””μŠ€ν¬λ¦½ν„°μ™€ 같은 기반 타이머 객체λ₯Ό 가리킀며, μžμ‹μ—μ„œ read(2) ν•˜λ©΄ κ·Έ νƒ€μ΄λ¨Έμ˜ λ§Œλ£Œμ— λŒ€ν•œ 정보λ₯Ό λ°˜ν™˜ν•˜κ²Œ λœλ‹€.

execve(2) λ™μž‘ 방식

timerfd_create()으둜 μƒμ„±ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ execve(2)λ₯Ό κ±°μΉ˜λ©΄μ„œ 보쑴되며, 타이머가 μž₯μ „λ˜μ–΄ μžˆμ—ˆλ‹€λ©΄ 계속 타이머 λ§Œλ£Œκ°€ λ°œμƒν•œλ‹€.

RETURN VALUE

성곡 μ‹œ timerfd_create()은 μƒˆ 파일 λ””μŠ€ν¬λ¦½ν„°λ₯Ό λ°˜ν™˜ν•œλ‹€. 였λ₯˜ μ‹œ -1을 λ°˜ν™˜ν•˜λ©° 였λ₯˜λ₯Ό λ‚˜νƒ€λ‚΄λ„λ‘ errnoλ₯Ό μ„€μ •ν•œλ‹€.

timerfd_settime()κ³Ό timerfd_gettime()은 성곡 μ‹œ 0을 λ°˜ν™˜ν•œλ‹€. 였λ₯˜ μ‹œ -1을 λ°˜ν™˜ν•˜λ©° 였λ₯˜λ₯Ό λ‚˜νƒ€λ‚΄λ„λ‘ errnoλ₯Ό μ„€μ •ν•œλ‹€.

ERRORS

timerfd_create()이 λ‹€μŒ 였λ₯˜λ‘œ μ‹€νŒ¨ν•  수 μžˆλ‹€.

EINVAL
clockid μΈμžκ°€ CLOCK_MONOTONICμ΄λ‚˜ CLOCK_REALTIME이 μ•„λ‹ˆλ‹€.
EINVAL
flagsκ°€ μœ νš¨ν•˜μ§€ μ•Šλ‹€. λ˜λŠ” λ¦¬λˆ…μŠ€ 2.6.26 λ˜λŠ” μ΄μ „μ—μ„œ flagsκ°€ 0이 μ•„λ‹ˆλ‹€.
EMFILE
μ—΄λ¦° 파일 λ””μŠ€ν¬λ¦½ν„° κ°œμˆ˜μ— λŒ€ν•œ ν”„λ‘œμ„ΈμŠ€λ³„ μ œν•œμ— λ„λ‹¬ν–ˆλ‹€.
ENFILE
μ—΄λ¦° 파일 μ΄κ°œμˆ˜μ— λŒ€ν•œ μ‹œμŠ€ν…œ μ „μ—­ μ œν•œμ— λ„λ‹¬ν–ˆλ‹€.
ENODEV
(λ‚΄λΆ€μ μœΌλ‘œ μ“°λŠ”) 읡λͺ… μ•„μ΄λ…Έλ“œ μž₯치λ₯Ό 마운트 ν•  수 μ—†μ—ˆλ‹€.
ENOMEM
타이머λ₯Ό μƒμ„±ν•˜κΈ°μ— 컀널 λ©”λͺ¨λ¦¬κ°€ μΆ©λΆ„ν•˜μ§€ μ•Šμ•˜λ‹€.

timerfd_settime()κ³Ό timerfd_gettime()이 λ‹€μŒ 였λ₯˜λ‘œ μ‹€νŒ¨ν•  수 μžˆλ‹€.

EBADF
fdκ°€ μœ νš¨ν•œ 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ μ•„λ‹ˆλ‹€.
EFAULT
new_valueλ‚˜ old_value, curr_valueκ°€ μœ νš¨ν•œ 포인터가 μ•„λ‹ˆλ‹€.
EINVAL
fdκ°€ μœ νš¨ν•œ timerfd 파일 λ””μŠ€ν¬λ¦½ν„°κ°€ μ•„λ‹ˆλ‹€.

timerfd_settime()이 λ‹€μŒ 였λ₯˜λ‘œ μ‹€νŒ¨ν•  μˆ˜λ„ μžˆλ‹€.

EINVAL
new_valueκ°€ μ˜¬λ°”λ‘œ μ΄ˆκΈ°ν™” λ˜μ–΄ μžˆμ§€ μ•Šλ‹€. (ν•œ tv_nsec ν•„λ“œκ°€ 0μ—μ„œ 999,999,999κΉŒμ§€ λ²”μœ„ 밖에 μžˆλ‹€.)
EINVAL
flagsκ°€ μœ νš¨ν•˜μ§€ μ•Šλ‹€.

VERSIONS

λ¦¬λˆ…μŠ€ 컀널 2.6.25λΆ€ν„° 이 μ‹œμŠ€ν…œ ν˜ΈμΆœλ“€μ΄ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€. glibc 버전 2.8λΆ€ν„° 라이브러리 지원을 μ œκ³΅ν•œλ‹€.

CONFORMING TO

이 μ‹œμŠ€ν…œ ν˜ΈμΆœλ“€μ€ λ¦¬λˆ…μŠ€ μ „μš©μ΄λ‹€.

BUGS

ν˜„μž¬ timerfd_create()κ°€ μ§€μ›ν•˜λŠ” 클럭 ID μ’…λ₯˜κ°€ timer_create(2)보닀 적닀.

EXAMPLE

λ‹€μŒ ν”„λ‘œκ·Έλž¨μ€ 타이머λ₯Ό μƒμ„±ν•˜κ³ μ„œ κ·Έ 진행을 μ§€μΌœλ³Έλ‹€. ν”„λ‘œκ·Έλž¨μ€ μ„Έ κ°œκΉŒμ§€μ˜ λͺ…λ Ήν–‰ 인자λ₯Ό λ°›λŠ”λ‹€. 첫 번째 μΈμžλŠ” νƒ€μ΄λ¨Έμ˜ 졜초 λ§Œλ£ŒκΉŒμ§€μ˜ 초 수λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 두 번째 μΈμžλŠ” νƒ€μ΄λ¨Έμ˜ 초 λ‹¨μœ„ 간격을 λ‚˜νƒ€λ‚Έλ‹€. μ„Έ 번째 μΈμžλŠ” μ’…λ£Œ μ „κΉŒμ§€ ν”„λ‘œκ·Έλž¨μ—μ„œ ν—ˆμš©ν•΄μ•Ό ν•˜λŠ” 타이머 만료 횟수λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 두 λ²ˆμ§Έμ™€ μ„Έ 번째 λͺ…λ Ήν–‰ μΈμžλŠ” 선택적이닀.

$ a.out 3 1 100
0.000: timer started
3.000: read: 1; total=1
4.000: read: 1; total=2
^Z                  # control+Z μž…λ ₯ν•΄μ„œ ν”„λ‘œκ·Έλž¨ μ •μ§€
[1]+  Stopped                 ./timerfd3_demo 3 1 100
$ fg                # λͺ‡ 초 후에 μ‹€ν–‰ 재개
a.out 3 1 100
9.660: read: 5; total=7
10.000: read: 1; total=8
11.000: read: 1; total=9
^C                  # control+C μž…λ ₯ν•΄μ„œ ν”„λ‘œκ·Έλž¨ 쀑단

ν”„λ‘œκ·Έλž¨ μ†ŒμŠ€

#include <sys/timerfd.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>        /* uint64_t μ •μ˜ */

#define handle_error(msg) \
        do { perror(msg); exit(EXIT_FAILURE); } while (0)

static void
print_elapsed_time(void)
{
    static struct timespec start;
    struct timespec curr;
    static int first_call = 1;
    int secs, nsecs;

    if (first_call) {
        first_call = 0;
        if (clock_gettime(CLOCK_MONOTONIC, &start) == -1)
            handle_error("clock_gettime");
    }

    if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1)
        handle_error("clock_gettime");

    secs = curr.tv_sec - start.tv_sec;
    nsecs = curr.tv_nsec - start.tv_nsec;
    if (nsecs < 0) {
        secs--;
        nsecs += 1000000000;
    }
    printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);
}

int
main(int argc, char *argv[])
{
    struct itimerspec new_value;
    int max_exp, fd;
    struct timespec now;
    uint64_t exp, tot_exp;
    ssize_t s;

    if ((argc != 2) && (argc != 4)) {
        fprintf(stderr, "%s init-secs [interval-secs max-exp]\n",
                argv[0]);
        exit(EXIT_FAILURE);
    }

    if (clock_gettime(CLOCK_REALTIME, &now) == -1)
        handle_error("clock_gettime");

    /* λͺ…λ Ήν–‰μ—μ„œ μ§€μ •ν•œ 졜초 만료 μ‹œκ°„μ™€ κ°„κ²©μœΌλ‘œ
       CLOCK_REALTIME μ ˆλŒ€ μ‹œκ°„ 타이머 생성 */

    new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
    new_value.it_value.tv_nsec = now.tv_nsec;
    if (argc == 2) {
        new_value.it_interval.tv_sec = 0;
        max_exp = 1;
    } else {
        new_value.it_interval.tv_sec = atoi(argv[2]);
        max_exp = atoi(argv[3]);
    }
    new_value.it_interval.tv_nsec = 0;

    fd = timerfd_create(CLOCK_REALTIME, 0);
    if (fd == -1)
        handle_error("timerfd_create");

    if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1)
        handle_error("timerfd_settime");

    print_elapsed_time();
    printf("timer started\n");

    for (tot_exp = 0; tot_exp < max_exp;) {
        s = read(fd, &exp, sizeof(uint64_t));
        if (s != sizeof(uint64_t))
            handle_error("read");

        tot_exp += exp;
        print_elapsed_time();
        printf("read: %llu; total=%llu\n",
                (unsigned long long) exp,
                (unsigned long long) tot_exp);
    }

    exit(EXIT_SUCCESS);
}

SEE ALSO

eventfd(2), poll(2), read(2), select(2), setitimer(2), signalfd(2), timer_create(2), timer_gettime(2), timer_settime(2), epoll(7), time(7)


2019-03-06

⚠️ **GitHub.com Fallback** ⚠️