select(2) - wariua/manpages-ko GitHub Wiki
select, pselect, FD_CLR, FD_ISSET, FD_SET, FD_ZERO - ๋๊ธฐ์ I/O ๋ค์คํ
/* POSIX.1-2001, POSIX.1-2008์ ๋ฐ๋ฅด๋ฉด */
#include <sys/select.h>
/* ์ด์ ํ์ค๋ค์ ๋ฐ๋ฅด๋ฉด */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);
#include <sys/select.h>
int pselect(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, const struct timespec *timeout,
const sigset_t *sigmask);
glibc ๊ธฐ๋ฅ ํ์ธ ๋งคํฌ๋ก ์๊ฑด (feature_test_macros(7) ์ฐธ๊ณ ):
-
pselect()
: _POSIX_C_SOURCE >= 200112L
select()
์ pselect()
๋ฅผ ์ด์ฉํด ํ๋ก๊ทธ๋จ์์ ์ฌ๋ฌ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ๊ฐ์ํ๊ณ ๊ทธ ์ค ํ๋ ์ด์์ด ์ด๋ค ์ ํ์ I/O ๋์์ "์ค๋น" ์ํ(๊ฐ๋ น, ์
๋ ฅ ๊ฐ๋ฅ)๊ฐ ๋ ๋๊น์ง ๋๊ธฐํ ์ ์๋ค. ํด๋น I/O ๋์(๊ฐ๋ น read(2)
๋ ์ถฉ๋ถํ ์์ write(2)
)์ ๋ธ๋กํน ์์ด ์ํํ๋ ๊ฒ ๊ฐ๋ฅํ๋ฉด ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ค๋น ์ํ๋ผ๊ณ ๋ณธ๋ค.
select()
์์๋ FD_SETSIZE
๋ณด๋ค ์์ ํ์ผ ๋์คํฌ๋ฆฝํฐ ๋ฒํธ๋ง ๊ฐ์ํ ์ ์๋ค. poll(2)์๋ ๊ทธ๋ฐ ์ ํ์ด ์๋ค. BUGS ์ฐธ๊ณ .
select()
์ pselect()
์ ๋์์ ๋ค์ ์ธ ๊ฐ์ง ์ฐจ์ด๋ฅผ ๋นผ๋ฉด ๋์ผํ๋ค.
(i) select()
์ ํ์์์์ struct timeval
(์ด์ ๋ง์ดํฌ๋ก์ด)์ด์ง๋ง pselect()
์์๋ struct timespec
(์ด์ ๋๋
ธ์ด)์ ์ด๋ค.
(ii) select()
์์๋ ๋จ์ ์๊ฐ์ด ์ผ๋ง์ธ์ง ๋ํ๋ด๊ธฐ ์ํด timeout
์ธ์๋ฅผ ๊ฐฑ์ ํ ์๋ ์๋ค. pselect()
์์๋ ๊ทธ ์ธ์๋ฅผ ๋ฐ๊พธ์ง ์๋๋ค.
(iii) select()
์๋ sigmask
์ธ์๊ฐ ์๊ณ , ๊ทธ๋์ sigmask
๋ฅผ NULL๋ก ํด์ ํธ์ถํ pselect()
์ฒ๋ผ ๋์ํ๋ค.
์ธ ๊ฐ์ง ๋
๋ฆฝ์ ์ธ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์งํฉ์ ๊ฐ์ํ๋ค. readfds
์ ๋์ด๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ์ฝ๊ธฐ ๊ฐ๋ฅํ ๋ฌธ์๊ฐ ์๋์ง ์ดํด๋ณธ๋ค. (๋ ์ ํํ๋ ์ฝ๊ธฐ๊ฐ ๋ธ๋ก ํ์ง ์์์ง ํ์ธํ๋ค. ํนํ ํ์ผ ๋์์๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ค๋น๋ ์ํ์ด๋ค.) writefds
์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ์ฐ๊ธฐ๋ฅผ ์ํ ๊ณต๊ฐ์ด ์๋์ง ์ดํด๋ณธ๋ค. (ํฐ ๋ฐ์ดํฐ๋ฅผ ์ฐ๋ฉด ์ฌ์ ํ ๋ธ๋กํ ์๋ ์๋ค.) exceptfds
์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ์์ธ ์ํฉ๋ค์ ํ์ธํ๋ค. (์์ธ ์ํฉ๋ค์ ๋ช ๊ฐ์ง ์๋ฅผ poll(2)์ POLLPRI
์ค๋ช
์์ ๋ณผ ์ ์๋ค.)
๋น ์ ธ ๋์ฌ ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์งํฉ ๊ฐ๊ฐ์ ์ค์ ์ํ๊ฐ ๋ฐ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ๋ํ๋ด๋๋ก ๋ณ๊ฒฝ๋์ด ์๋ค. (๋ฐ๋ผ์ ๋ฃจํ ์์์ select()
๋ฅผ ์ด๋ค๋ฉด ํธ์ถ ์ ์ ๋งค๋ฒ ์งํฉ์ ๋ค์ ์ค์ ํด์ผ ํ๋ค.)
ํด๋น ์ด๋ฒคํธ ์ ํ์ ๋ํด ๊ฐ์ํ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์๋ค๋ฉด ์ธ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์งํฉ ๊ฐ๊ฐ์ NULL๋ก ์ง์ ํ ์๋ ์๋ค.
์งํฉ ์กฐ์์ ์ํ ๋งคํฌ๋ก ๋ค ๊ฐ์ง๊ฐ ์๋ค. FD_ZERO()
๋ ์งํฉ์ ๋น์ด๋ค. FD_SET()
๊ณผ FD_CLR()
๋ ์งํฉ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ํ๊ณ ๋บ๋ค. FD_ISSET()
์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์งํฉ์ ํฌํจ๋ผ ์๋์ง ํ์ธํ๋๋ฐ, select()
๋ฐํ ํ์ ์ฐ๊ฒ ๋๋ค.
nfds
๋ ์ธ ์งํฉ์์ ๋ฒํธ๊ฐ ๊ฐ์ฅ ๋์ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ 1์ ๋ํ ๊ฐ์ผ๋ก ์ค์ ํ๋ฉด ๋๋ค. ๊ฐ ์งํฉ์์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ํ์๋ผ ์๋์ง๋ฅผ ๊ทธ ์ ํ์น๊น์ง ํ์ธํ๋ค. (ํ์ง๋ง BUGS ์ฐธ๊ณ .)
timeout
์ธ์๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ค๋น ์ํ๊ฐ ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ฉฐ select()
์์ ๋ธ๋ก ํ ์๊ฐ์ ๋ํ๋ธ๋ค. ๋ค์ ์ด๋ ๊ฒฝ์ฐ๋ ํด๋นํ ๋๊น์ง ํธ์ถ์ด ๋ธ๋ก ํ๊ฒ ๋๋ค.
-
ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ค๋น ์ํ๊ฐ ๋๋ค.
-
ํธ์ถ์ด ์๊ทธ๋ ํธ๋ค๋ฌ์ ์ํด ์ค๋จ๋๋ค.
-
ํ์์์์ด ๋ง๋ฃ๋๋ค.
์ฐธ๊ณ ๋ก timeout
์๊ฐ์ ์์คํ
ํด๋ญ ํด์๋์ ๋ฐ๋ผ ์ฌ๋ฆผ ํ๊ฒ ๋๋ฉฐ ์ปค๋ ์ค์ผ์ค๋ง ์ง์ฐ๋ ์๊ธฐ ๋๋ฌธ์ ๊ทธ ๋ธ๋ก ์๊ฐ์ ์ฝ๊ฐ ๋๊ธธ ์๋ ์๋ค. timeval
๊ตฌ์กฐ์ฒด์ ๋ ํ๋๊ฐ ๋ชจ๋ 0์ด๋ฉด select()
๊ฐ ์ฆ์ ๋ฐํํ๋ค. (ํด๋ง์ ์ ์ฉํ๋ค.) timeout
์ด NULL์ด๋ฉด (ํ์์์์ด ์์ผ๋ฉด) select()
์์ ๋ฌดํ์ ๋ธ๋ก ํ ์ ์๋ค.
sigmask
๋ ์๊ทธ๋ ๋ง์คํฌ(sigprocmask(2) ์ฐธ๊ณ )์ ๋ํ ํฌ์ธํฐ๋ค. NULL์ด ์๋ ๊ฒฝ์ฐ pselect()
์์๋ ๋จผ์ ํ์ฌ ์๊ทธ๋ ๋ง์คํฌ๋ฅผ sigmask
๊ฐ ๊ฐ๋ฆฌํค๋ ๋ง์คํฌ๋ก ๊ต์ฒดํ๊ณ , "select" ๋์์ ํ๊ณ ์, ์๋ ์๊ทธ๋ ๋ง์คํฌ๋ฅผ ๋ณต์ํ๋ค.
timeout
์ธ์์ ์ ๋ฐ๋ ์ฐจ์ด๋ฅผ ์ ์ธํ๋ฉด ๋ค์ pselect()
ํธ์ถ์
ready = pselect(nfds, &readfds, &writefds, &exceptfds,
timeout, &sigmask);
๋ค์ ํธ์ถ๋ค์ ์์์ ์ผ๋ก ์คํํ๋ ๊ฒ๊ณผ ๋๋ฑํ๋ค.
sigset_t origmask;
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ready = select(nfds, &readfds, &writefds, &exceptfds, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);
pselect()
๊ฐ ํ์ํ ์ด์ ๋ ์๊ทธ๋๊ณผ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์ํ ๋ณํ๋ฅผ ํจ๊ป ๊ธฐ๋ค๋ฆฌ๋ ค ํ ๋ ๊ฒฝ์ ์กฐ๊ฑด์ ๋ง์ผ๋ ค๋ฉด ์์์ ๊ฒ์ฌ๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ด๋ค. (์๊ทธ๋ ํธ๋ค๋ฌ์์ ์ ์ญ ํ๋๊ทธ๋ฅผ ์ค์ ํ๊ณ ๋ฐํํ๋ค๊ณ ํ์. ๊ทธ ์ ์ญ ํ๋๊ทธ๋ฅผ ๊ฒ์ฌํ ๋ค์์ select()
ํธ์ถ์ ํ๋ค๊ณ ํ ๋, ๊ฒ์ฌ ํ์ด์ ํธ์ถ ์ ์ ์๊ทธ๋์ด ๋์ฐฉํ๋ค๋ฉด ํธ์ถ์ด ๋ฌดํ์ ๋ฉ์ถฐ ์์ ์๋ ์๋ค. ๋ฐ๋ฉด pselect()
๋ฅผ ์ฐ๋ ๊ฒฝ์ฐ์๋ ์ผ๋จ ์๊ทธ๋๋ค์ ๋ง์ ๋๊ณ , ๋ค์ด์จ ์๊ทธ๋๋ค์ ์ฒ๋ฆฌํ ๋ค์์ ์ํ๋ sigmask
๋ก pselect()
๋ฅผ ํธ์ถํ์ฌ ๊ฒฝ์์ ํผํ ์ ์๋ค.)
๊ด๋ จ๋ ์๊ฐ ๊ตฌ์กฐ์ฒด๋ค์ด <sys/time.h>
์ ์ ์๋ผ ์์ผ๋ฉฐ ๋ค์๊ณผ ๊ฐ์ ํํ์ด๋ค.
struct timeval {
long tv_sec; /* ์ด */
long tv_usec; /* ๋ง์ดํฌ๋ก์ด */
};
struct timespec {
long tv_sec; /* ์ด */
long tv_nsec; /* ๋๋
ธ์ด */
};
(ํ์ง๋ง ์๋์ POSIX.1 ๋ฒ์ ๋ค ์ฐธ๊ณ .)
์ด๋ค ์ฝ๋์์๋ ์ธ ์งํฉ์ ๋ชจ๋ ๋น์ฐ๊ณ nfds
๋ฅผ 0์ผ๋ก ํ๊ณ ์ NULL ์๋ timeout
์ ์จ์ select()
๋ฅผ ํธ์ถํ๋๋ฐ, ์ด๋ ์ด ๋จ์ ์ดํ ์ ๋ฐ๋๋ก ์ ์ ์ ์๋ ๊ฝค ์ด์์ฑ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
๋ฆฌ๋
์ค์์๋ ์ ์์ง ์์ ์๊ฐ์ ์์ ๋ฐ์ํ๋๋ก timeout
์ ๋ณ๊ฒฝํ๋ค. ํ์ง๋ง ๋๋ถ๋ถ์ ๋ค๋ฅธ ๊ตฌํ๋ค์์๋ ๊ทธ๋ฌ์ง ์๋๋ค. (POSIX.1์์๋ ์ด๋ ์ชฝ ๋์์ด๋ ํ์ฉํ๋ค.) ์ด ๋๋ฌธ์ timeout
์ ์ฝ๋ ๋ฆฌ๋
์ค ์ฝ๋๋ฅผ ๋ค๋ฅธ ์ด์ ์ฒด์ ๋ก ์ด์ํ ๋, ๊ทธ๋ฆฌ๊ณ ๋ฃจํ์์ struct timeval
์ ์ฌ์ค์ ํ์ง ์๊ณ select()
์ฌ๋ฌ ๋ฒ์ ์ฌ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ๋ฆฌ๋
์ค๋ก ์ด์ํ ๋ ๋ฌธ์ ๊ฐ ์๊ธด๋ค. select()
๋ฐํ ํ์ timeout
์ ๊ฐ์ ๊ท์ ๋ผ ์์ง ์๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
์ฑ๊ณต ์ select()
์ pselect()
๋ ๋ฐํ๋๋ ์ธ ๋์คํฌ๋ฆฝํฐ ์งํฉ์ ๋ด๊ธด ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ์๋ฅผ (์ฆ readfds
, writefds
, exceptfds
์ ์ค์ ๋ ๋นํธ๋ค์ ์ด๊ฐ์๋ฅผ) ๋ฐํํ๋ค. ๋ญ๊ฐ ์ด๋ฒคํธ๊ฐ ์๊ธฐ๊ธฐ ์ ์ ํ์์์์ด ๋ง๋ฃ๋๋ค๋ฉด 0์ผ ์๋ ์๋ค. ์ค๋ฅ ์ -1์ ๋ฐํํ๋ฉฐ ์ค๋ฅ๋ฅผ ๋ํ๋ด๋๋ก errno
๋ฅผ ์ค์ ํ๋ค. ๊ทธ ๊ฒฝ์ฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์งํฉ๋ค์ ๋ณ๊ฒฝ๋์ง ์์ผ๋ฉฐ timeout
์ ๊ท์ ๋์ง ์์ ์ํ๊ฐ ๋๋ค.
EBADF
- ํ ์งํฉ์ ์ ํจํ์ง ์์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์๋ค. (์๋ง ์ด๋ฏธ ๋ซํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ผ ๊ฒ์ด๋ค.) ํ์ง๋ง BUGS ์ฐธ๊ณ .
EINTR
- ์๊ทธ๋์ ์ก์๋ค. signal(7) ์ฐธ๊ณ .
EINVAL
-
nfds
๊ฐ ์์์ด๊ฑฐ๋RLIMIT_NOFILE
์์ ์ ํ๊ฐ(getrlimit(2) ์ฐธ๊ณ )์ ์ด๊ณผํ๋ค. EINVAL
-
timeout
์ ๋ด๊ธด ๊ฐ์ด ์ ํจํ์ง ์๋ค. ENOMEM
- ๋ด๋ถ ํ ์ด๋ธ์ ์ํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ ์ ์๋ค.
๋ฆฌ๋
์ค ์ปค๋ 2.6.16์์ pselect()
๊ฐ ์ถ๊ฐ๋์๋ค. ๊ทธ ์ ์๋ glibc์์ pselect()
๋ฅผ ์๋ฎฌ๋ ์ด์
ํ๋ค. (ํ์ง๋ง BUGS ์ฐธ๊ณ .)
select()
๋ POSIX.1-2001, POSIX.1-2008, 4.4BSD๋ฅผ (4.2BSD์์ select()
๊ฐ ์ฒ์ ๋ฑ์ฅ) ์ค์ํ๋ค. BSD ์์ผ ๊ณ์ธต ๋ณต์ ํํ๋ฅผ ์ง์ํ๋ BSD ์ธ ์์คํ
๋ค(์์คํ
V ๊ณ์ด ํฌํจ)๊ณผ์ ์ฌ์ด์์ ์ผ๋ฐ์ ์ผ๋ก ์๋ก ์ด์ ๊ฐ๋ฅํ๋ค. ํ์ง๋ง ์์คํ
V ๊ณ์ด์์๋ ๋ณดํต ๋์ค๊ธฐ ์ ์ ํ์์์ ๋ณ์๋ฅผ ์ค์ ํ๋ ๋ฐ๋ฉด BSD ๊ณ์ด์์๋ ๊ทธ๋ฌ์ง ์๋๋ค.
pselect()
๋ POSIX.1g์, ๊ทธ๋ฆฌ๊ณ POSIX.1-2001 ๋ฐ POSIX.1-2008์ ๊ท์ ๋ผ ์๋ค.
fd_set
์ ๊ณ ์ ํฌ๊ธฐ ๋ฒํผ์ด๋ค. ์์์ด๊ฑฐ๋ FD_SETSIZE
์ ๊ฐ๊ฑฐ๋ ๋ ํฐ fd
๊ฐ์ผ๋ก FD_CLR()
์ด๋ FD_SET()
์ ์คํํ ๋์ ๋์ ๋ฐฉ์์ ๊ท์ ๋ผ ์์ง ์๋ค. ๋ํ POSIX์์๋ fd
๊ฐ ์ ํจํ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ฌ์ผ ํ๋ค๊ณ ์๊ตฌํ๋ค.
select()
๋ฐ pselect()
์ ๋์์ O_NONBLOCK
ํ๋๊ทธ์ ์ํฅ์ ๋ฐ์ง ์๋๋ค.
์ผ๋ถ ๋ค๋ฅธ ์ ๋์ค ์์คํ
์์๋ ์ปค๋ ๋ด๋ถ ์์์ ํ ๋นํ์ง ๋ชปํ์ ๋ ๋ฆฌ๋
์ค์ ENOMEM
์ด ์๋๋ผ EAGAIN
์ค๋ฅ๋ก ์คํจํ ์ ์๋ค. POSIX์์ poll(2)์ ์ด ์ค๋ฅ๋ฅผ ๋ช
์ธํ๊ณ ์์ง๋ง select()
์ ๋ํด์ ์๋๋ค. ์ด์ ๊ฐ๋ฅํ ํ๋ก๊ทธ๋จ์์๋ EAGAIN
์ ํ์ธํด์ EINTR
๊ฒฝ์ฐ์ฒ๋ผ ๋ฃจํ๋ฅผ ๊ณ์ ๋๋ ๊ฒ ์ข์ ์ ์๋ค.
pselect()
๊ฐ ์๋ ์์คํ
์์๋ ์๊ฐ ํ์ดํ ์๋ น์ ์จ์ ์ ๋ขฐ์ฑ ์๊ฒ (๊ทธ๋ฆฌ๊ณ ๋ ์ด์์ฑ ์๊ฒ) ์๊ทธ๋ ์ก๊ธฐ๋ฅผ ํ ์ ์๋ค. ์ด ๊ธฐ๋ฒ์ ์๊ทธ๋ ํธ๋ค๋ฌ์์ ํ์ดํ๋ก ํ ๋ฐ์ดํธ๋ฅผ ์จ๋ฃ๊ณ ๊ทธ ๋ฐ๋์ชฝ์ ์ฃผ ํ๋ก๊ทธ๋จ์ select()
๋ก ๊ฐ์ํ๋ ๊ฒ์ด๋ค. (๊ฐ๋ ์ฐฌ ํ์ดํ์ ์จ๋ฃ๊ฑฐ๋ ๋น ํ์ดํ์์ ์ฝ์ ๋ ๋ธ๋ก ๋ ๊ฐ๋ฅ์ฑ์ ํผํ๊ธฐ ์ํด ํ์ดํ์ ์ฝ๊ณ ์ธ ๋ ๋
ผ๋ธ๋กํน I/O๋ฅผ ์ด๋ค.)
์ฌ์ฉ ํ์
๊ณผ ๊ด๋ จํด์ ์ ํต์ ํ๊ฒฝ์์๋ timeval
๊ตฌ์กฐ์ฒด์ ๋ ํ๋๊ฐ (์์ ๋ณด์ธ ๊ฒ์ฒ๋ผ) long
ํ์
์ผ๋ก ๋์ด ์์ผ๋ฉฐ ๊ทธ ๊ตฌ์กฐ์ฒด๊ฐ <sys/time.h>
์ ์ ์๋ผ ์๋ค. ํ์ง๋ง POSIX.1 ํ๊ฒฝ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
struct timeval {
time_t tv_sec; /* ์ด */
suseconds_t tv_usec; /* ๋ง์ดํฌ๋ก์ด */
};
<sys/select.h>
์ ๊ตฌ์กฐ์ฒด๊ฐ ์ ์๋ผ ์์ผ๋ฉฐ ๋ฐ์ดํฐ ํ์
time_t
์ suseconds_t
๋ <sys/types.h>
์ ์ ์๋ผ ์๋ค.
์ํ๊ณผ ๊ด๋ จํด์ ์ ํต์ ํ๊ฒฝ์์๋ select()
๋ฅผ ์ํด์ <time.h>
๋ฅผ ํฌํจ์์ผ์ผ ํ๋ค. POSIX.1 ํ๊ฒฝ์์๋ select()
์ pselect()
๋ฅผ ์ํด <sys/select.h>
๋ฅผ ํฌํจ์์ผ์ผ ํ๋ค.
glibc 2.0 ํ์์ <sys/select.h>
์ด ์ ๊ณตํ๋ pselect()
์ํ์ด ์๋ชป๋ผ ์๋ค. glibc 2.1์์ 2.2.1๊น์ง ํ์์ _GNU_SOURCE
๊ฐ ์ ์๋ผ ์์ ๋ pselect()
๋ฅผ ์ ๊ณตํ๋ค. glibc 2.2.2๋ถํฐ๋ ์๊ฑด์ด SYNOPSIS์ ๋์ ์๋ ๋๋ก์ด๋ค.
๋ฆฌ๋
์ค ์ปค๋ ์์ค์์ ์ฐพ์ ์ ์๋ ๋ค์ ์ ์๋ค์ด select()
์ ์ฝ๊ธฐ ๊ฐ๋ฅ, ์ฐ๊ธฐ ๊ฐ๋ฅ, ์์ธ ์ํฉ ์๋ฆผ๊ณผ poll(2)(๊ณผ epoll(7))์์ ์ ๊ณตํ๋ ์ด๋ฒคํธ ์๋ฆผ ์ฌ์ด์ ๋์ ๊ด๊ณ๋ฅผ ๋ณด์ฌ ์ค๋ค.
#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP |
POLLERR)
/* ์ฝ๊ธฐ ์ค๋น๋จ */
#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
/* ์ฐ๊ธฐ ์ค๋น๋จ */
#define POLLEX_SET (POLLPRI)
/* ์์ธ ์ํฉ */
select()
๋ก ๊ฐ์ ์ค์ธ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ค๋ฅธ ์ค๋ ๋์์ ๋ซ๋ ๊ฒฝ์ฐ์ ๊ฒฐ๊ณผ๋ ๋ช
์ธ๋ผ ์์ง ์๋ค. ์ด๋ค ์ ๋์ค ์์คํ
์์๋ select()
๊ฐ ๋ธ๋ก์ ๋ฉ์ถ๊ณ ๋ฐํํ๋ฉฐ ๊ทธ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ค๋น ์ํ๋ผ๊ณ ํ์ํ๋ค. (๊ทธ๋ฌ๋ฉด ์ด์ด์ง๋ I/O ๋์์ด ์ค๋ฅ๋ก ์คํจํ๊ฒ ๋๋ค. ๋จ select()
๋ฐํ ์์ ๊ณผ I/O ๋์ ์ํ ์์ ์ฌ์ด์ ๋ค๋ฅธ ํ๋ก์ธ์ค์์ ๊ทธ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ค์ ์ด์ง ์์์ผ ํ๋ค.) ๋ฆฌ๋
์ค์์๋ (๊ทธ๋ฆฌ๊ณ ์ด๋ค ๋ค๋ฅธ ์์คํ
์์๋) ๋ค๋ฅธ ์ค๋ ๋์์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ซ๋ ๊ฒ select()
์ ์ํฅ์ ์ฃผ์ง ์๋๋ค. ์์ปจ๋ฐ ์ด ์ํฉ์์ ํน์ ๋์ ๋ฐฉ์์ ์์กดํ๋ ์์ฉ์ ๋ฒ๊ทธ๊ฐ ์๋ ๊ฒ์ผ๋ก ๋ด์ผ ํ๋ค.
๋ฆฌ๋
์ค ์ปค๋์์๋ ์์ ํฌ๊ธฐ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์งํฉ์ด ๊ฐ๋ฅํ๊ณ nfds
์ ๊ฐ์ผ๋ก ๊ฒ์ฌํ ์งํฉ์ ๊ธธ์ด๋ฅผ ์์๋ธ๋ค. ํ์ง๋ง glibc ๊ตฌํ์์๋ fd_set
ํ์
์ ๊ธธ์ด๊ฐ ๊ณ ์ ๋ผ ์๋ค. BUGS๋ ์ฐธ๊ณ .
์ด ํ์ด์ง์์ ๊ธฐ์ ํ๋ pselect()
์ธํฐํ์ด์ค๋ glibc์์ ๊ตฌํํ๊ณ ์๋ค. ๊ธฐ๋ฐ ๋ฆฌ๋
์ค ์์คํ
ํธ์ถ์ ์ด๋ฆ์ pselect6()
์ด๋ค. ์ด ์์คํ
ํธ์ถ์ glibc ๋ํผ ํจ์์ ๋์ ๋ฐฉ์์ด ์ข ๋ค๋ฅด๋ค.
๋ฆฌ๋
์ค์ pselect6()
์์คํ
ํธ์ถ์์๋ timeout
์ธ์๋ฅผ ๋ณ๊ฒฝํ๋ค. ํ์ง๋ง glibc ๋ํผ ํจ์์์ ํ์์์ ์ธ์์ ๋ํ ์ง์ญ ๋ณ์๋ฅผ ์ฐ๊ณ ๊ทธ ๋ณ์๋ฅผ ์์คํ
ํธ์ถ๋ก ์ ๋ฌํ์ฌ ๊ทธ ๋์ ๋ฐฉ์์ ๊ฐ์ถ๋ค. ๊ทธ๋ฆฌํ์ฌ glibc์ pselect()
ํจ์๋ timeout
์ธ์๋ฅผ ๋ณ๊ฒฝํ์ง ์๋๋ค. ์ด๋ POSIX.1-2001์์ ์๊ตฌํ๋ ๋์ ๋ฐฉ์์ด๋ค.
pselect6()
์์คํ
ํธ์ถ์ ๋ง์ง๋ง ์ธ์๋ sigset_t *
ํฌ์ธํฐ๊ฐ ์๋๋ผ ๋ค์ ํํ์ ๊ตฌ์กฐ์ฒด์ด๋ค.
struct {
const kernel_sigset_t *ss; /* ์๊ทธ๋ ์งํฉ์ ๋ํ ํฌ์ธํฐ */
size_t ss_len; /* 'ss'๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด์ ํฌ๊ธฐ
(๋ฐ์ดํธ ๋จ์) */
};
๊ทธ๋์ ์ฌ๋ฌ ์ํคํ ์ฒ์์ ์์คํ ํธ์ถ์ ์ต๋ 6๊ฐ ์ธ์๋ง ์ง์ํ๋ค๋ ์ ์ ๊ฐ์ํ๋ฉด์ ์์คํ ํธ์ถ์์ ์๊ทธ๋ ์งํฉ ํฌ์ธํฐ์ ๊ทธ ํฌ๊ธฐ๋ฅผ ๋ชจ๋ ๋ฐ์ ์ ์๋ค. ์ปค๋๊ณผ libc์์์ ์๊ทธ๋ ์งํฉ ๊ฐ๋ ์ฐจ์ด์ ๋ํ ์ค๋ช ์ sigprocmask(2)๋ฅผ ๋ณด๋ผ.
POSIX์์๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์งํฉ์ ์ง์ ํ ์ ์๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ๋ฒ์์ ๋ํด ๊ตฌํ์์ ์ํ์ ์ ํด์ ์์ FD_SETSIZE
๋ฅผ ํตํด ์๋ฆฌ๋ ๊ฒ์ ํ์ฉํ๋ค. ๋ฆฌ๋
์ค ์ปค๋์์๋ ์ด๋ค ๊ณ ์ ์ ํ๋ ๋์ง ์์ง๋ง glibc ๊ตฌํ์์๋ FD_SETSIZE
๋ฅผ 1024๋ก ํด์ fd_set
์ ๊ณ ์ ํฌ๊ธฐ ํ์
์ผ๋ก ๋ง๋ค๊ณ FD_*()
๋งคํฌ๋ก๊ฐ ๊ทธ ์ ํ์ ๋ฐ๋ผ ๋์ํ๊ฒ ํ๋ค. 1023๋ณด๋ค ํฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๊ฐ์ํ๋ ค๋ฉด poll(2)์ ์จ์ผ ํ๋ค.
fd_set
์ธ์๊ฐ ๊ฐ-๊ฒฐ๊ณผ ์ธ์๋ก ๊ตฌํ๋ผ ์์ผ๋ฏ๋ก select()
๋ฅผ ํธ์ถํ ๋๋ง๋ค ๋ค์ ์ค์ ํด ์ค์ผ ํ๋ค. poll(2)์์๋ ํธ์ถ์ ์
๋ ฅ๊ณผ ์ถ๋ ฅ์ ๋ณ๋์ ๊ตฌ์กฐ์ฒด ํ๋๋ฅผ ์ฌ์ฉํด์ ์ด ์ค๊ณ ์ค๋ฅ๋ฅผ ํผํ๋ค.
POSIX์ ๋ฐ๋ฅด๋ฉด select()
์์๋ ์ธ ํ์ผ ๋์คํฌ๋ฆฝํฐ ์งํฉ์ ์ง์ ๋ ๋ชจ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ์ํ nfds-1
๊น์ง ํ์ธํด์ผ ํ๋ค. ํ์ง๋ง ํ์ฌ ๊ตฌํ์์๋ ํ๋ก์ธ์ค๊ฐ ํ์ฌ ์ด์ด ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ ๋ฒํธ์ ์ต๋๊ฐ๋ณด๋ค ํฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฌด์ํ๋ค. POSIX์ ๋ฐ๋ฅด๋ฉด ํ ์งํฉ์ ๊ทธ๋ฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ง์ ๋ผ ์์ผ๋ฉด EBADF
์ค๋ฅ๊ฐ ๋ฐ์ํด์ผ ํ๋ค.
glibc 2.0์์๋ sigmask
์ธ์๋ฅผ ๋ฐ์ง ์๋ pselect()
๋ฒ์ ์ ์ ๊ณตํ๋ค.
glibc ๋ฒ์ 2.1๋ถํฐ sigprocmask(2)์ select()
๋ฅผ ์ด์ฉํด ๊ตฌํํ pselect()
์๋ฎฌ๋ ์ด์
์ ์ ๊ณตํ๋ค. ๊ทธ ๊ตฌํ์ pselect()
๊ฐ ๋ฐฉ์งํด์ผ ํ๋ ๋ฐ๋ก ๊ทธ ๊ฒฝ์ ์กฐ๊ฑด์ ์ฌ์ ํ ์ทจ์ฝํ๋ค. ์ต๊ทผ์ glibc ๋ฒ์ ๋ค์์๋ ์ปค๋์์ (๊ฒฝ์ ์๋) pselect()
์์คํ
ํธ์ถ์ ์ ๊ณตํ๋ฉด ๊ทธ๊ฑธ ์ด๋ค.
๋ฆฌ๋
์ค์์๋ select()
์์ ์ด๋ค ์์ผ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ "์ฝ๊ธฐ ์ค๋น๋จ"์ผ๋ก ๋ณด๊ณ ํ๋๋ฐ ์ด์ด์ง๋ ์ฝ๊ธฐ๊ฐ ๋ธ๋ก ๋ ์๋ ์๋ค. ์๋ฅผ ๋ค์ด ๋ฐ์ดํฐ๊ฐ ๋์ฐฉํ์ง๋ง ์กฐ์ฌํด ๋ณด๋ ์ฒดํฌ์ฌ์ด ํ๋ ค์ ํ๊ธฐํ ๋ ๊ทธ๋ด ์ ์๋ค. ๊ทธ ์ธ์๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์ค๋น ์ํ๋ผ๊ณ ์๋ชป ๋ณด๊ณ ํ๋ ๋ค๋ฅธ ๊ฒฝ์ฐ๋ค์ด ์์ ์ ์๋ค. ๋ฐ๋ผ์ ๋ธ๋ก ํด์๋ ์ ๋๋ ์์ผ์์๋ O_NONBLOCK
์ ์ฐ๋ ๊ฒ ์์ ํ ์ ์๋ค.
๋ฆฌ๋
์ค์์๋ ์๊ทธ๋ ํธ๋ค๋ฌ์ ์ํด ํธ์ถ์ด ์ค๋จ๋ ๊ฒฝ์ฐ(์ฆ EINTR
์ค๋ฅ ๋ฐํ)์๋ select()
์์ timeout
์ ๋ณ๊ฒฝํ๋ค. ์ด๋ POSIX.1์์ ํ์ฉํ์ง ์๋ ๋์์ด๋ค. ๋ฆฌ๋
์ค์ pselect()
์์คํ
ํธ์ถ๋ ๋์ผํ๊ฒ ๋์ํ์ง๋ง glibc ๋ํผ์์ ๋ด๋ถ์ ์ผ๋ก timeout
์ ์ง์ญ ๋ณ์๋ก ๋ณต์ฌํ๊ณ ๊ทธ ๋ณ์๋ฅผ ์์คํ
ํธ์ถ์ ์ ๋ฌํจ์ผ๋ก์จ ๊ทธ ๋์ ๋ฐฉ์์ ๊ฐ์ถ๋ค.
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int
main(void)
{
fd_set rfds;
struct timeval tv;
int retval;
/* stdin(fd 0)์ ์
๋ ฅ์ด ์๋์ง ๊ฐ์. */
FD_ZERO(&rfds);
FD_SET(0, &rfds);
/* 5์ด๊น์ง ๊ธฐ๋ค๋ฆผ. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
/* tv์ ๊ฐ์ ์์กดํ์ง ๋ง ๊ฒ! */
if (retval == -1)
perror("select()");
else if (retval)
printf("Data is available now.\n");
/* FD_ISSET(0, &rfds)๊ฐ ์ฐธ์. */
else
printf("No data within five seconds.\n");
exit(EXIT_SUCCESS);
}
accept(2)
, connect(2)
, poll(2), read(2)
, recv(2), restart_syscall(2), send(2), sigprocmask(2), write(2)
, epoll(7), time(7)
์ค๋ช ๊ณผ ์์๊ฐ ์๋ ์์ต์์ธ select_tut(2) ์ฐธ๊ณ .
2019-03-06