eventfd(2) - wariua/manpages-ko GitHub Wiki
eventfd - ์ด๋ฒคํธ ์๋ฆผ์ ์ํ ํ์ผ ๋์คํฌ๋ฆฝํฐ ๋ง๋ค๊ธฐ
#include <sys/eventfd.h>
int eventfd(unsigned int initval, int flags);
eventfd()
๋ "eventfd ๊ฐ์ฒด"๋ฅผ ์์ฑํ๋ฉฐ, ์ด๋ฅผ ์ฌ์ฉ์ ๊ณต๊ฐ ์์ฉ์์ ์ด๋ฒคํธ ๋๊ธฐ/์๋ฆผ ๋ฉ์ปค๋์ฆ์ผ๋ก ์ฌ์ฉํ๊ฑฐ๋ ์ปค๋์์ ์ฌ์ฉ์ ๊ณต๊ฐ ์์ฉ์๊ฒ ์ด๋ฒคํธ๋ฅผ ์๋ฆฌ๋ ๋ฐ ์ธ ์ ์๋ค. ๊ทธ ๊ฐ์ฒด์๋ ์ปค๋์์ ๊ด๋ฆฌํ๋ ๋ถํธ ์๋ 64๋นํธ ์ ์ (uint64_t
) ์นด์ดํฐ๊ฐ ์๋ค. ์ธ์ initval
์ ์ง์ ํ ๊ฐ์ผ๋ก ๊ทธ ์นด์ดํฐ๋ฅผ ์ด๊ธฐํ ํ๋ค.
๋ฐํ ๊ฐ์ผ๋ก eventfd()
๋ ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฐํํ๋ฉฐ ์ด๋ฅผ ์ด์ฉํด eventfd ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
flags
์ ๋ค์ ๊ฐ๋ค์ ๋นํธ OR ํด์ eventfd()
์ ๋์ ๋ฐฉ์์ ๋ฐ๊ฟ ์ ์๋ค.
-
EFD_CLOEXEC
(๋ฆฌ๋ ์ค 2.6.27๋ถํฐ) - ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ 'exec์์ ๋ซ๊ธฐ'(
FD_CLOEXEC
) ํ๋๊ทธ๋ฅผ ์ค์ ํ๋ค. ์ด๊ฒ ์ ์ฉํ ์ ์๋ ์ด์ ์ ๋ํด์ open(2)์O_CLOEXEC
ํ๋๊ทธ ์ค๋ช ์ ๋ณด๋ผ. -
EFD_NONBLOCK
(๋ฆฌ๋ ์ค 2.6.27๋ถํฐ) - ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ์ด๋ฆฐ ํ์ผ ๊ธฐ์ ํญ๋ชฉ(open(2) ์ฐธ๊ณ )์
O_NONBLOCK
ํ์ผ ์ํ ํ๋๊ทธ๋ฅผ ์ค์ ํ๋ค. ์ด ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ ์ํด fcntl(2)์ ์ถ๊ฐ๋ก ํธ์ถํ์ง ์์๋ ๋๋ค. -
EFD_SEMAPHORE
(๋ฆฌ๋ ์ค 2.6.30๋ถํฐ) - ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์ฝ๊ธฐ์ ์ธ๋งํฌ์ด ๊ฐ์ ๋์ ๋ฐฉ์์ ์ ๊ณตํ๋ค. ์๋ ์ฐธ๊ณ .
๋ฆฌ๋
์ค ๋ฒ์ 2.6.26๊น์ง๋ flags
์ธ์๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉฐ 0์ผ๋ก ์ง์ ํด์ผ ํ๋ค.
eventfd()
๊ฐ ๋ฐํํ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ ๋ค์ ์์
์ ์ํํ ์ ์๋ค.
read(2)
-
read(2)
๊ฐ ์ฑ๊ณตํ ๋๋ง๋ค 8๋ฐ์ดํธ ์ ์๋ฅผ ๋ฐํํ๋ค. ์ ๊ณต๋ฐ์ ๋ฒํผ์ ํฌ๊ธฐ๊ฐ 8๋ฐ์ดํธ๋ณด๋ค ์์ผ๋ฉดread(2)
๊ฐEINVAL
์ค๋ฅ๋ก ์คํจํ๋ค.read(2)
๊ฐ ๋ฐํํ๋ ๊ฐ์ ํธ์คํธ ๋ฐ์ดํธ ์์, ์ฆ ํธ์คํธ ๋จธ์ ์๋์ ์ ์ ๋ฐ์ดํธ ์์์ด๋ค.read(2)
์ ๋์ ๋ฐฉ์์ eventfd ์นด์ดํฐ๊ฐ ํ์ฌ 0 ์๋ ๊ฐ์ ๊ฐ์ง๊ณ ์๋์ง ์ฌ๋ถ์ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ ์์ฑ ์EFD_SEMAPHORE
ํ๋๊ทธ๋ฅผ ์ง์ ํ๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ค.-
EFD_SEMAPHORE
๋ฅผ ์ง์ ํ์ง ์์๊ณ eventfd ์นด์ดํฐ์ ๊ฐ์ด 0์ด ์๋๋ฉดread(2)
๊ฐ ๊ทธ ๊ฐ์ ๋ด์ 8๋ฐ์ดํธ๋ฅผ ๋ฐํํ๋ฉฐ ์นด์ดํฐ ๊ฐ์ด 0์ผ๋ก ์ฌ์ค์ ๋๋ค. -
EFD_SEMAPHORE
๋ฅผ ์ง์ ํ์ผ๋ฉฐ eventfd ์นด์ดํฐ์ ๊ฐ์ด 0์ด ์๋๋ฉดread(2)
๊ฐ ๊ฐ 1์ ๋ด์ 8๋ฐ์ดํธ๋ฅผ ๋ฐํํ๋ฉฐ ์นด์ดํฐ ๊ฐ์ด 1๋งํผ ์ค์ด๋ ๋ค. -
read(2)
ํธ์ถ ์์ ์ eventfd ์นด์ดํฐ๊ฐ 0์ด๋ฉด ์นด์ดํฐ๊ฐ 0์ด ์๋๊ฒ ๋ ๋๊น์ง ๋ธ๋ก ํ๋ค. (๊ทธ๋read(2)
๊ฐ ์ ์ค๋ช ์ฒ๋ผ ์งํํ๋ค.) ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ ผ๋ธ๋ก์ผ๋ก ๋ง๋ค์์ผ๋ฉดEAGAIN
์ค๋ฅ๋ก ์คํจํ๋ค.
-
write(2)
-
write(2)
ํธ์ถ์ ๋ฒํผ์ ์ค 8๋ฐ์ดํธ ์ ์ ๊ฐ์ ์นด์ดํฐ์ ๋ํ๋ค. ์นด์ดํฐ์ ์ ์ฅํ ์ ์๋ ์ต๋๊ฐ์ ๊ฐ์ฅ ํฐ ๋ถํธ ์๋ 64๋นํธ ์ ์์์ 1์ ๋บ ๊ฒ(์ฆ 0xfffffffffffffffe)์ด๋ค. ๋ํ ๊ฒฐ๊ณผ๊ฐ ๊ทธ ์ต๋๊ฐ์ ์ด๊ณผํ๊ฒ ๋ ๊ฒ ๊ฐ์ผ๋ฉด ๊ทธ ํ์ผ ๋์คํฌ๋ฆฝํฐ์read(2)
๊ฐ ์ด๋ค์ง ๋๊น์งwrite(2)
๊ฐ ๋ธ๋ก ํ๋ค. ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ ผ๋ธ๋ก์ผ๋ก ๋ง๋ค์์ผ๋ฉดEAGAIN
์ค๋ฅ๋ก ์คํจํ๋ค.์ ๊ณต ๋ฒํผ์ ํฌ๊ธฐ๊ฐ 8๋ฐ์ดํธ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ 0xffffffffffffffff๋ฅผ ์ฐ๋ ค๊ณ ์๋ํ๋ฉด
write(2)
๊ฐEINVAL
์ค๋ฅ๋ก ์คํจํ๋ค. - poll(2), select(2) (๊ธฐํ ์ ์ฌ ํจ์)
-
๋ฐํ๋๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ๋ค์๊ณผ ๊ฐ์ด poll(2) (epoll(7)๋ ๋น์ทํจ) ๋ฐ select(2)๋ฅผ ์ง์ํ๋ค.
-
์นด์ดํฐ ๊ฐ์ด 0๋ณด๋ค ํฌ๋ฉด ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ฝ๊ธฐ ๊ฐ๋ฅํ๋ค. (select(2)์
readfds
์ธ์, poll(2)์POLLIN
ํ๋๊ทธ) -
๋ธ๋ก ๋์ง ์๊ณ ์ ์ด๋ "1" ๊ฐ์ ๊ธฐ๋กํ ์ ์์ผ๋ฉด ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ฐ๊ธฐ ๊ฐ๋ฅํ๋ค. (select(2)์
writefds
์ธ์, poll(2)์POLLOUT
ํ๋๊ทธ) -
์นด์ดํฐ ๊ฐ ์ค๋ฒํ๋ก์ฐ๋ฅผ ๊ฐ์งํ ๊ฒฝ์ฐ select(2)๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ฝ๊ธฐ ๊ฐ๋ฅํ๋ฉด์ ๋์์ ์ฐ๊ธฐ ๊ฐ๋ฅํ๋ค๊ณ ํ์ํ๋ฉฐ poll(2)์
POLLERR
์ด๋ฒคํธ๋ฅผ ๋ฐํํ๋ค. ์์์ ์ธ๊ธํ ๊ฒ์ฒ๋ผwrite(2)
๋ ์ ๋ ์นด์ดํฐ๋ฅผ ๋์น๊ฒ ํ ์ ์๋ค. ํ์ง๋ง KAIO ์๋ธ์์คํ ์์ eventfd "์๋ฆผ ๋ฐ์ก"์ 2^64๋ฒ ์ํํ๋ค๋ฉด ๋์นจ์ด ๋ฐ์ํ ์ ์๋ค. (์ด๋ก ์ ์ผ๋ก ๊ฐ๋ฅํ ๊ฒ์ด๊ณ ์ค์ ๋ก๋ ๊ฐ๋ฅ์ฑ์ด ๋ฎ๋ค.) ๋์นจ์ด ๋ฐ์ํ์ผ๋ฉดread(2)
๊ฐ ๊ฐ์ฅ ํฐuint64_t
๊ฐ(์ฆ 0xffffffffffffffff)์ ๋ฐํํ๊ฒ ๋๋ค.
eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ pselect(2)์ ppoll(2) ๊ฐ์ ๋ค๋ฅธ ํ์ผ ๋์คํฌ๋ฆฝํฐ ๋ค์คํ API๋ ์ง์ํ๋ค.
-
- close(2)
- ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ๋ ์ด์ ํ์ํ์ง ์์ผ๋ฉด ๋ซ์์ผ ํ๋ค. ๋์ผ eventfd ๊ฐ์ฒด์ ์ฐ๊ณ๋ ๋ชจ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ๋ซํ์ ๋ ์ปค๋์ด ๊ทธ ๊ฐ์ฒด์ ์์์ ํด์ ํ๋ค.
fork(2)๋ก ์์ฑ๋ ์์์ eventfd()
๋ก ๋ง๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ ์ฌ๋ณธ์ ๋ฌผ๋ ค๋ฐ๋๋ค. ๋ณต์ ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ ๋์ผํ eventfd ๊ฐ์ฒด์ ์ฐ๊ณ๋์ด ์๋ค. 'exec์์ ๋ซ๊ธฐ' ํ๋๊ทธ๋ฅผ ์ค์ ํ์ง ์์์ผ๋ฉด execve(2)๋ฅผ ๊ฑฐ์น๋ฉด์ eventfd()
๋ก ๋ง๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ ์ง๋๋ค.
์ฑ๊ณต ์ eventfd()
๋ ์ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฐํํ๋ค. ์ค๋ฅ ์ -1์ ๋ฐํํ๋ฉฐ ์ค๋ฅ๋ฅผ ๋ํ๋ด๋๋ก errno
๋ฅผ ์ค์ ํ๋ค.
EINVAL
- ์ง์ํ์ง ์๋ ๊ฐ์
flags
์ ์ง์ ํ๋ค. EMFILE
- ์ด๋ฆฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ ๊ฐ์์ ๋ํ ํ๋ก์ธ์ค๋ณ ์ ํ์ ๋๋ฌํ๋ค.
ENFILE
- ์ด๋ฆฐ ํ์ผ ์ด๊ฐ์์ ๋ํ ์์คํ ์ ์ญ ์ ํ์ ๋๋ฌํ๋ค.
ENODEV
- (๋ด๋ถ์ ์ผ๋ก ์ฐ๋) ์ต๋ช ์์ด๋ ธ๋ ์ฅ์น๋ฅผ ๋ง์ดํธ ํ ์ ์์๋ค.
ENOMEM
- ์ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ์์ฑํ๊ธฐ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ถฉ๋ถํ์ง ์์๋ค.
๋ฆฌ๋
์ค ์ปค๋ 2.6.22๋ถํฐ eventfd()
๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. glibc ๋ฒ์ 2.8๋ถํฐ ์ ๋์ํ๋ ์ง์์ ์ ๊ณตํ๋ค. ๋ฆฌ๋
์ค ์ปค๋ 2.6.27๋ถํฐ eventfd2()
์์คํ
ํธ์ถ(NOTES ์ฐธ๊ณ )์ด ์ฌ์ฉ ๊ฐ๋ฅํ๋ค. ๋ฒ์ 2.9๋ถํฐ glibc์ eventfd()
๋ํผ๊ฐ ์ปค๋ ์ง์ ์ eventfd2()
์์คํ
ํธ์ถ์ ์ด์ฉํ๋ค.
์ด ์ ์์ ์ฌ์ฉํ๋ ์ฉ์ด๋ค์ ๋ํ ์ค๋ช ์ attributes(7)๋ฅผ ๋ณด๋ผ.
์ธํฐํ์ด์ค | ์์ฑ | ๊ฐ |
---|---|---|
eventfd() |
์ค๋ ๋ ์์ ์ฑ | MT-Safe |
eventfd()
์ eventfd2()
๋ ๋ฆฌ๋
์ค ์ ์ฉ์ด๋ค.
์์ฉ์์ ํ์ดํ(pipe(2) ์ฐธ๊ณ )๋ฅผ ์ด๋ฒคํธ ์ ๋ฌ์ฉ์ผ๋ก๋ง ์ฐ๋ ๋ชจ๋ ๊ฒฝ์ฐ์์ ํ์ดํ ๋์ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ค. eventfd์ ์ปค๋ ์ค๋ฒํค๋๊ฐ ํ์ดํ๋ณด๋ค ํจ์ฌ ๋ฎ์ผ๋ฉฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ํ ๊ฐ๋ง ํ์ํ๋ค. (ํ์ดํ์์๋ ๋ ๊ฐ๊ฐ ํ์ํ๋ค.)
์ปค๋์์ ์ฌ์ฉ ์ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ ์ปค๋์์ ์ฌ์ฉ์ ๊ณต๊ฐ์ผ๋ก์ ๊ฐ๊ต๊ฐ ๋ ์ ์๋ค. ๊ทธ๋์ ์๋ฅผ ๋ค์ด KAIO(์ปค๋ AIO) ๊ฐ์ ๊ธฐ๋ฅ์์ ์ด๋ค ๋์์ด ์๋ฃ๋์์ ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ก ์๋ฆด ์ ์๋ค.
eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ์ ํต์ฌ์ ์ฌ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ฒ๋ผ select(2)๋ poll(2), epoll(7)์ ์ด์ฉํด ์ํ๋ฅผ ํ์ธํ ์ ์๋ค๋ ์ ์ด๋ค. ๊ทธ๋์ ์์ฉ์์ "์ ํต์ " ํ์ผ์ ์ค๋น ์ํ์ eventfd ์ธํฐํ์ด์ค๋ฅผ ์ง์ํ๋ ์ปค๋ ๋ฉ์ปค๋์ฆ์ ์ค๋น ์ํ๋ฅผ ๋์์ ํ์ธํ ์ ์๋ค. (eventfd()
์ธํฐํ์ด์ค๊ฐ ์์ผ๋ฉด ๊ทธ ๋ฉ์ปค๋์ฆ์ select(2)๋ poll(2), epoll(7)์ ํตํด ๋ค์คํ ํ ์ ์์์ ๊ฒ์ด๋ค.)
ํ๋ก์ธ์ค์ /proc/[pid]/fdinfo
๋๋ ํฐ๋ฆฌ ๋ด์ ๋์ํ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ ํญ๋ชฉ์ ํตํด eventfd ์นด์ดํฐ์ ํ์ฌ ๊ฐ์ ๋ณผ ์ ์๋ค. ์์ธํ ๋ด์ฉ์ proc(5) ์ฐธ๊ณ .
๊ธฐ๋ฐ ์์คํ
ํธ์ถ์ด ๋ ๊ฐ์ง ์๋ค. eventfd()
์ ๋ ์ต์ ์ธ eventfd2()
์ด๋ค. ์์ชฝ ์์คํ
ํธ์ถ์ flags
์ธ์๋ฅผ ๊ตฌํํ์ง ์๋๋ค. ๋ค์ชฝ ์์คํ
ํธ์ถ์ ์์ ๊ธฐ์ ํ flags
๊ฐ๋ค์ ๊ตฌํํ๋ค. glibc ๋ํผ ํจ์์์ ๊ฐ๋ฅํ ๊ฒฝ์ฐ eventfd2()
๋ฅผ ์ฌ์ฉํ๋ค.
GNU C ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์๋ก์ด ํ์ ํ๋์ ํจ์ ๋ ๊ฐ๋ฅผ ์ ์ํ๊ณ ์๋๋ฐ, ์ด๋ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ ์ฝ๊ธฐ์ ์ฐ๊ธฐ์ ์ธ๋ถ ์ฌํญ์ ์ข ์ถ์ํ ํด ๋ณด๋ ค๋ ๊ฒ์ด๋ค.
typedef uint64_t eventfd_t;
int eventfd_read(int fd, eventfd_t *value);
int eventfd_write(int fd, eventfd_t value);
์ด ํจ์๋ค์ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ์ ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ๋์์ ์ํํ๋ฉฐ, ์ ํํ ์์ ๋ฐ์ดํธ๋ฅผ ์ ์กํ์ผ๋ฉด 0์ ๋ฐํํ๊ณ ์๋๋ฉด -1์ ๋ฐํํ๋ค.
์๋ ํ๋ก๊ทธ๋จ์ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ง๋ค๊ณ ์ ๋ถ๊ธฐํ์ฌ ์์ ํ๋ก์ธ์ค๋ฅผ ๋ง๋ ๋ค. ๋ถ๋ชจ๊ฐ ์ ์ ์ ๋๋ ๋์ ์์์ด ํ๋ก๊ทธ๋จ ๋ช ๋ นํ ์ธ์๋ก ๋ฐ์ ์ ์๋ค ๊ฐ๊ฐ์ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ์ ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์์ ๊นฌ ๋ถ๋ชจ๊ฐ eventfd ํ์ผ ๋์คํฌ๋ฆฝํฐ์์ ์ฝ๊ธฐ๋ฅผ ํ๋ค.
๋ค์ ์ ธ ์ธ์ ์ ํ๋ก๊ทธ๋จ ์คํ ์๋ฅผ ๋ณด์ฌ ์ค๋ค.
$ ./a.out 1 2 4 7 14
Child writing 1 to efd
Child writing 2 to efd
Child writing 4 to efd
Child writing 7 to efd
Child writing 14 to efd
Child completed write loop
Parent about to read
Parent read 28 (0x1c) from efd
#include <sys/eventfd.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)
int
main(int argc, char *argv[])
{
int efd, j;
uint64_t u;
ssize_t s;
if (argc < 2) {
fprintf(stderr, "Usage: %s <num>...\n", argv[0]);
exit(EXIT_FAILURE);
}
efd = eventfd(0, 0);
if (efd == -1)
handle_error("eventfd");
switch (fork()) {
case 0:
for (j = 1; j < argc; j++) {
printf("Child writing %s to efd\n", argv[j]);
u = strtoull(argv[j], NULL, 0);
/* strtoull()์ ๋ค์ํ ๊ธฐ์ ๊ฐ๋ฅ */
s = write(efd, &u, sizeof(uint64_t));
if (s != sizeof(uint64_t))
handle_error("write");
}
printf("Child completed write loop\n");
exit(EXIT_SUCCESS);
default:
sleep(2);
printf("Parent about to read\n");
s = read(efd, &u, sizeof(uint64_t));
if (s != sizeof(uint64_t))
handle_error("read");
printf("Parent read %llu (0x%llx) from efd\n",
(unsigned long long) u, (unsigned long long) u);
exit(EXIT_SUCCESS);
case -1:
handle_error("fork");
}
}
futex(2), pipe(2), poll(2), read(2)
, select(2), signalfd(2), timerfd_create(2), write(2)
, epoll(7), sem_overview(7)
2019-03-06