선택(유닉스)
select (Unix)select는 Unix 계열 및 POSIX 준거 운영체제시스템에서의 시스템콜 및 Application Programming Interface(API; 응용 프로그램프로그래밍 인터페이스)로 오픈 입출력 [1]채널의 파일 기술자 상태를 조사합니다.셀렉트 시스템콜은 UNIX System V 이후의 운영시스템에서 도입된 폴링 기능과 비슷합니다.단, c10k 문제에서는 선택 포트와 폴링 모두 kqueue,[2] epoll, /dev/poll 및 I/O 완료 포트와 같은 것으로 대체되었습니다.
select의 일반적인 용도는 파일 핸들 대기 이외의 것으로, 휴대 가능한 sleep을 1초 미만의 sleeve를 실장하는 것입니다.이것은 3개의 fd_set 인수 모두에 대해 NULL을 전달하고 timeout 인수로 원하는 sleep 시간을 전달함으로써 달성할 수 있습니다.
C 프로그래밍 언어에서는 select system 콜은 헤더파일 sys/select.h 또는 unistd.h로 선언되며 구문은 다음과 같습니다.
인트 선택한다.(인트 nfds, fd_set *판독, fd_set *기입하다, fd_set *에러, 구조 타임밸 *타임아웃); | 논쟁 | 묘사 |
|---|---|
| nfds | 이것은, 모든 세트의 파일 기술자의 최대수보다 1 많은 정수입니다.즉, 각 세트에 파일 기술자를 추가할 때 모든 파일의 최대 정수값을 계산하고 이 값을 1씩 증가시킨 후 nfds로 전달해야 합니다. |
| 판독 | fd_set type은 읽을 준비가 되었는지 확인할 파일 기술자를 보관하고 있으며, 출력은 읽을 준비가 된 파일 기술자를 나타냅니다.NULL일 수 있습니다. |
| 기입하다 | fd_set type에는 기입 준비가 되어 있는지 체크할 파일 기술자가 저장되어 있습니다.출력에는 기입 준비가 되어 있는 파일 기술자가 표시됩니다.NULL일 수 있습니다. |
| 에러 | fd_set type은 보류 중인 오류 조건을 체크하는 파일 기술자를 보유하고 있으며, 출력 시 보류 중인 오류 조건이 있는 파일 기술자를 나타냅니다.NULL일 수 있습니다. |
| 타임아웃 | 선택이 완료될 때까지 대기하는 최대 간격을 지정하는 구조 시간 간격의 구조입니다.timeout 인수가 멤버가0 인 구조 timeval 타입의 개체를 가리킬 경우 select()는 차단하지 않습니다.timeout 인수가 NULL인 경우 이벤트로 인해 마스크 중 하나가 유효한 값(0이 아닌 값)으로 반환될 때까지 차단합니다.Linux 에서는 타임아웃이 갱신되어 경과시간이 표시됩니다.단, 이 동작은 대부분의 다른 Unix 시스템에서는 공유되지 않습니다. |
fd_set type인수는 FD_SET(), FD_CLR(), FD_ZERO() 및 FD_의 4가지 유틸리티 매크로를 사용하여 조작할 수 있습니다.ISSET()
선택하면 readfds, writefds 및 errorfds에 설정된 총 비트 수가 반환됩니다. 타임아웃이 만료된 경우 0이 반환되고 오류 발생 시 -1이 반환됩니다.
선택에서 사용되는 파일 기술자 세트는 운영 체제에 따라 크기가 제한됩니다.새로운 시스템콜 폴링을 통해 보다 유연한 솔루션을 얻을 수 있습니다.
예
#실패하다 <stdio.h> #실패하다 <stdlib.h> #실패하다 <문자열>h> #실패하다 < sys / types >h> #실패하다 <sys/module >h> #실패하다 <netnet/in.h> #실패하다 <netdb.h> #실패하다 <sys/select.h> #실패하다 <fcntl.h> #실패하다 <리스트 없음.h> #실패하다 <err.h> #실패하다 <errno.h> # 포트 "9421" 정의 /* 기능 프로토타입 */ 무효 죽어버려(컨스턴트 차*); 인트 주된(인트 argc, 차 **argv) { 인트 양말, 신규, 최대값, 에 = 1, 준비 완료, i; 구조 어드린포 *res0, *인식하다, 힌트; 차 완충 장치[부후즈]; fd_set 마스터., 판독; 인트 에러; ssize_t 바이트 수; (무효)메모리 세트(&힌트, '\0', 크기(구조 어드린포)); 힌트.ai_패밀리 = AF_INET; 힌트.ai_syslog 타입 = 양말_스트림; 힌트.ai_module = IPPROTO_TCP; 힌트.ai_module = AI_PASSIVE; 한다면 (0 != (에러 = getaddrinfo(특수한 순서, 항구, &힌트, &res0))) 에러(EXIT_FAILURE, %s, gai_crror(에러)); 위해서 (인식하다 = res0; 인식하다; 인식하다 = 인식하다->ai_다음) { 한다면 (-1 == (양말 = 소켓(인식하다->ai_패밀리, 인식하다->ai_syslog 타입, 인식하다->ai_module))) { 에러("timeout()"); 계속하다.; } 한다면 (-1 == (셋소켓(양말, SOL_SOCKET, SO_REUSEADDR, (차*)&에, 크기(인트)))) { 에러("setsockopt()"); 계속하다.; } 한다면 (-1 == (묶다(양말, 인식하다->ai_addr, 인식하다->ai_addrlen))) { 에러("timeout()"); 계속하다.; } 브레이크.; } 한다면 (-1 == 양말) 퇴장(EXIT_FAILURE); 프리 어드 정보(res0); 한다면 (-1 == (들어봐(양말, 32))) 죽어버려("listen()"); 한다면 (-1 == (fcntl(양말, F_SETFD, O_NONBLOCK(비블록)))) 죽어버려("fcntl()"); FD_ZERO(&마스터.); FD_ZERO(&판독); FD_SET(양말, &마스터.); 최대값 = 양말; 하는 동안에 (1) { 메모리(&판독, &마스터., 크기(마스터.)); (무효)인쇄물("선택() 실행 중"\n"); 한다면 (-1 == (준비 완료 = 선택한다.(최대값+1, &판독, 특수한 순서, 특수한 순서, 특수한 순서))) 죽어버려("select()"); (무효)인쇄물("준비 기술자 수: %d\n", 준비 완료); 위해서 (i=0; i<=>최대값 & & 준비 완료>0; i++) { 한다면 (FD_ISSET(i, &판독)) { 준비 완료--; 한다면 (i == 양말) { (무효)인쇄물("새 연결을 수락()하려고 합니다.\n"); 한다면 (-1 == (신규 = 받아들이다(양말, 특수한 순서, 특수한 순서))) { 한다면 (차단하다 != 에러) 죽어버려("accept()"); 브레이크.; } 또 다른 { 한다면 (-1 == (fcntl(신규, F_SETFD, O_NONBLOCK(비블록)))) 죽어버려("fcntl()"); FD_SET(신규, &마스터.); 한다면 (최대값 < > 신규) 최대값 = 신규; } } 또 다른 { (무효)인쇄물(기술자 중 하나에서 "recv() 데이터"\n"); 바이트 수 = 인식하다(i, 완충 장치, 크기(완충 장치), 0); 한다면 (바이트 수 <=> 0) { 한다면 (차단하다 != 에러) 죽어버려("recv()"); 브레이크.; } 완충 장치[바이트 수] = '\0'; 인쇄물(%s, 완충 장치); (무효)인쇄물(%zi 바이트가 수신되었습니다.\n", 바이트 수); 가까운.(i); FD_CLR(i, &마스터.); } } } } 돌아가다 0; } 무효 죽어버려(컨스턴트 차 *메시지) { 에러(메시지); 퇴장(EXIT_FAILURE); } 「 」를 참조해 주세요.
레퍼런스
- ^ Computer Systems Research Group (1994). "select, pselect — synchronous I/O multiplexing". BSD Cross Reference. NetBSD.
- ^ "Connection processing methods". nginx.org.
외부 링크
- – System Interfaces Reference, 단일 UNIX 사양, The Open Group 버전 4
- 의 맨 페이지
select(2)FreeBSD, NetBSD, OpenBSD 및 DragonFly BSD의 경우