부모 프로세스가 서버 프로세스로 동작, 자신과 통신하는 클라이언트 (자식 프로세스) 를 임의의 수만큼 가지는 경우 사용
#include <sys/time.h>
int select(int nfds, fd_set *readsfs, fd_set *writefs, fd_set *errorfs, struct timeval *timeout);
int main(){
//서버 1, 클라이언트 2인 상황
int fd1, fd2;
fd_set readset;
fd1 = open("file1", O_RDONLY);
fd2 = open(file2", O_RDONLY);
FD_ZERO(&readset);
FD_SET(fd1, &readset);
FD_SET(fd2, &readset);
switch(select(5,&readset,NULL,NULL,NULL)){ //읽을 데이터 있을 때까지 봉쇄
}
}
- nfds : 서버가 잠재적 흥미 가지는 (사용할) 파일 기술자의 수
- 0(stdin), 1(stdout), 2(stderr)는 default, 두 개의 파일을 더 개방하면 nfds = 5
- fd_set으로 정의된 인수들은 비트마스크
- 각 비트가 하나의 파일기술자 나타냄, 한 비트 켜져 있으면 해당 파일 기술자에 대한 흥미 나타냄
- readfs : 읽을 가치 있는 것 있는가?
- writefs : 임의의 주어진 파일 기술자가 쓰기 받아들일 준비 됐는가?
- errorfs : 주어진 파일 기술자 중 하나라도 오류 발생했는가?
- fdset이 가리키는 마스크 관련 함수
- FD_ZERO(fd set *fdset); - fdset이 가리키는 마스크 초기화
- FD_SET(int fd, fd_set *fdset); - fdset이 가리키는 마스크 내의 비트, fd를 1로 설정
- FD_ISSET(int fd, fd_set *fdset); - fdset이 가리키는 마스크내의 비트, fd가 설정되어 있는가?
- FD_CLR(int fd, fd_set *fdset); - fdset이 가리키는 마스크내의 비트, fd를 0으로 설정
- timeout : struct timeval 에 대한 포인터
- 포인터가 NULL : select는 흥미 있는 일 일어날 때까지 봉쇄됨
timeout이 0초 포함하는 구조 가리키면 즉각 복귀
0 아닌 값 포함하고 있으면 지정된 시간 후에 복귀
- 포인터가 NULL : select는 흥미 있는 일 일어날 때까지 봉쇄됨
- select의 복귀 값은 오류 시 -1, 타임 아웃 시 0, 아니면 흥미 있는 파일 기술자의 수 나타내는 정수
예시
#define MSGSIZE 6
char *msg1 = "hello";
char *msg2 = "bye!!";
void parent(int p[3][2]);
int child(int[]);
main() {
int pip[3][2];
int i;
for (i=0; i<3; i++) {
pipe(pip[i]);
switch(fork()) {
case -1: perror("fork call");
case 0 : child(pip[i]);
}
}
parent(pip);
exit(0);
}
void parent(int p[3][2]) {
char buf[MSGSIZE], ch;
fd_set set, master;
int i;
for (i=0; i<3; i++) close(p[i][1]);
FD_ZERO(&master);
FD_SET(0, &master);
for (i=0; i<3; i++) FD_SET(p[i][0], &master);
while (set = master, select(p[2][0]+1, &set, NULL, NULL, NULL) > 0) {
if (FD_ISSET(0, &set)) {
printf("From standard input ...");
read(0, &ch, 1);
printf("%c\n", ch);
}
for (i=0; i<3; i++) {
if (FD_ISSET(p[i][0], &set)) {
if (read(p[i][0], buf, MSGSIZE) > 0) {
printf("Message from child %d\n", i);
printf("MSG=%s\n", buf);
}
}
}
if (waitpid (-1, NULL, WNOHANG) == -1) return;
}
}
int child(int p[2]) {
int count;
close (p[0]);
for (count = 0; count < 2; count ++) {
write(p[1], msg1, MSGSIZE);
sleep(getpid() % 4);
}
write(p[1], msg2, MSGSIZE);
exit(0);
}