시스템 호출을 선택하기위한 첫 번째 인수의 목적은 무엇입니까?


25

에서 man select

int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout);

nfds는 세 세트 중 하나에 1을 더한 파일 번호입니다.

의 목적은 무엇인가 nfds, 우리가 이미 가지고있는 경우 readfds, writefds그리고 exceptfds,있는 파일 설명이 결정될 수는?


SO에 대해 묻려고했지만 여기에 더 집중되어 있으며 C API 호출은 주제별로 간주됩니다 .
phunehehe 2019

답변:


25

에서 "유닉스 환경에서 고급 프로그래밍" , W. 리처드 스티븐스는 성능 최적화 말한다 :

우리가 가장 관심있는 디스크립터를 지정함으로써, 커널은 세 개의 디스크립터 세트에서 사용되지 않는 비트 수백 개를 거치지 않고 켜져있는 비트를 찾습니다.

(399 페이지 1 판)

모든 종류의 UNIX 시스템 프로그래밍을 수행하는 경우 APUE 서적을 적극 권장합니다.


최신 정보

fd_set일반적으로 1024 파일 설명까지 추적 할 수 있습니다.

어느 fds것이 설정되어 0있고 어떤 것이 설정되어 있는지 추적하는 가장 효율적인 방법 은 비트 세트 1이므로 각각 fd_set은 1024 비트로 구성됩니다.

그 수단에 각각 있도록 32 비트 시스템에서 긴 INT (또는 "단어")는 32 비트 fd_set이다
32분의 1,024 = 32 즉.

경우 nfds뭔가 작은 등이 많은 응용 프로그램에있을 것입니다 8 또는 16으로, 그것은 단지 명확하게 빨리 모든 (32)의 내부보고보다해야 할 첫번째 단어, 내부 볼 필요가있다.

(참조 FD_SETSIZE__NFDBITS에서 /usr/include/sys/select.h플랫폼에 값.)


업데이트 2

함수 서명이 아닌 이유에 관해서

int select(fd_set *readfds, int nreadfds,
           fd_set *writefds, int nwritefds,
           fd_set *exceptfds, int nexceptfds,
           struct timeval *timeout);

내 생각에 코드가 모든 인수를 레지스터 에 유지하려고 시도하기 때문에 CPU가 더 빨리 작동 할 수 있으며 추가 2 변수를 추적 해야하는 경우 CPU에 레지스터가 충분하지 않을 수 있습니다.

즉, select구현 세부 사항을 더 빨리 노출 할 수 있도록 구현 세부 정보를 노출시키는 것입니다.



APUE도 최근에 업데이트되었습니다. 제 2 판 : amazon.com/gp/aw/d.html/ref=aw_d_detail?pd=1&a=0201433079
Mikel

@ chris 나는 리눅스 프로그래밍 인터페이스를 점검 할 것이다. 감사.
Mikel

정보 주셔서 감사합니다, 나는 시간을 잡을 때 책을 확인합니다.
phunehehe

APUE 2nd Ed : 2005 년 6 월 27 일 (linux-2.4.22 커버) TLPI : 2010 년 10 월 (linux-2.6.35 커버)
chris

6

select ()의 디자이너가 아니기 때문에 확실하지 않지만 성능 최적화라고 말하고 싶습니다. 호출 함수는 FD에 읽기, 쓰기 및 제외에 넣은 파일 디스크립터 수를 알고 있으므로 커널이 다시 이해해야하는 이유는 무엇입니까?

80 년대 초, select ()가 소개되었을 때, 다중 기가 헤르츠, 다중 프로세서는 없었습니다. 25MHz VAX는 매우 빠르다. 또한 select ()가 다음과 같은 경우에 빠르게 작동하기를 원했습니다. 일부 I / O가 프로세스를 기다리고있는 경우 프로세스를 대기하게 만드는 이유


당신의 주장에 우리가해야 할 말을 nreadfds, nwritefds그리고 nexceptfds대신 하나 nfds.
phunehehe

어쩌면 nfds빠른 액세스를 위해 레지스터에 들어갈 수 있습니다. 다른 모든 인수와 함께 세 개의 숫자를 추적해야한다면 CPU에 충분한 레지스터가 없을 수 있습니다. 물론 커널은 nfds가상의 3 가지 변수를 기반으로 자체 커널을 만들 수 있습니다 . 그래서 제 추측은 효율성을 얻기 위해 구현 세부 사항을 노출시키는 것입니다.
Mikel

@Mikel, phunehehe : 별도의 nfds주장은 거의 이익을 얻지 못할 것입니다. 대부분의 경우 프로세스는에 대한 프로세스를 거의 열지 않았습니다 FD_SETSIZE. 일반적인 경우는 1024 개 중 (4,4,2)를 가질 수 있습니다. 커널 검사 (4,4,4)를 만드는 것은 (1024,1024,1024)의 큰 승리이지만 (4,4,2)까지 최적화하는 것은 거의 쓸모가 없습니다.
Gilles 'SO- 악마 그만'

@Gilles : 게인은 더 깨끗한 API입니다. (따라서 프로그래머는 계산을 위해 추가 작업을 수행 nfds하거나 게으르고 호출 select(FD_SETSIZE, ...)해야합니다. 느릴 것입니다.)
Mikel

프로그래머에게는 최대 변수 하나만 추적하는 것이 더 쉬울 수 있습니다.
Mikel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.