선택(유닉스)

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, writefdserrorfds에 설정된 총 비트 수가 반환됩니다. 타임아웃이 만료된 경우 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); } 

「 」를 참조해 주세요.

레퍼런스

  1. ^ Computer Systems Research Group (1994). "select, pselect — synchronous I/O multiplexing". BSD Cross Reference. NetBSD.
  2. ^ "Connection processing methods". nginx.org.

외부 링크