epoll, poll, threadpool의 차이점은 무엇입니까?
누군가가 차이가 사이에 무엇인지 설명 할 수 epoll
, poll
및 무언가?
- 장단점은 무엇입니까?
- 프레임 워크에 대한 제안이 있습니까?
- 간단한 / 기본 안내에 대한 제안 제안 사항이 있습니까?
- 보인다 것으로
epoll
및poll
윈도우 용 이에 상응하는 대안이 있는가 ... 리눅스 전용입니까?
Threadpool은 실제로 여론 조사 및 epoll과 동일한 범주에 속하지있는 "연결 당 하나의 단일로 많은 연결을 처리하는 단일 풀"에서와 같이 표준 풀을 참조합니다.
장점과 단점
- 대표 풀
- 중소 동시성에 합리적으로는 다른 기술을 사용할 수도 있습니다.
- 다중 코어를 사용합니다.
- 일부 시스템 (예 : Linux)이 원칙적으로 100,000 개의 단서를 잘 예약 할 수 있습니다. "수백 개"
- 순진한 구현은 " thundering herd "문제를 나타냅니다 .
- 전환 및 천둥 무리와는 특히 기억을 기억합니다. 각 단위에는 스택이 있습니다 (일반적으로 최소 1MB). 따라서 천 개의 단위는 스택에만 1 기가 바이트의 RAM을 사용합니다. 32 비트 OS에서는 상당한 주소가 제공됩니다 (실제로 64 비트에서는 제공됩니다).
- 스레드 수 실제로 사용하는
epoll
추론 확실한 방법 (모든 스레드가 차단 불구하고epoll_wait
) 아무 소용이는 epoll에 깨어 있기 때문에, 모든 것이 기다리고 스레드가 여전히 같은 문제를 가지게됩니다.- 최적의 솔루션 : 단일 한 epoll에서 수신 대기하고 입력 멀티플렉싱을 수행하며 전체 요청을 풀에 전달합니다.
futex
예를 들어 내용 당 빨리 감기와 함께 여기에서 친구입니다. 문서화가 나쁘고 다루기 힘들지만futex
정확히 필요한 것을 제공합니다.epoll
한 번에 여러 이벤트를 반환futex
할 수 있고 완벽하고 정확하게 제어 된 방식으로 한 번에 N 개의 차단 된 호출을 깨울 수 및 (min(num_cpu, num_events)
이상적으로는 N ), 최상의 경우에는 추가 시스템 / 모든 전환이 전혀 포함되지 않습니다. .- 구현하기가 쉽지 않고 약간의주의를 기울입니다.
fork
(일명 구식 풀)- 중소 동시성에 대해 합리적으로입니다.
- "수백"이상으로 확장되지 않습니다.
- 많이 스위치는 훨씬 더 비쌉니다 (다른 주소 공간!).
- (모든 페이지의 딥 카피) 오래된 시스템에서 훨씬 더 나빠도 비싼 비용입니다. 그러나
fork
대부분의 경우 COW (copy-on-write) 현대 에 의해 합쳐 지지만 시스템은 "무료"아닙니다. 수정 또한 되는 대규모 데이터 세트 에서 상당한 수의 페이지 오류fork
가 성능에 부정적인 영향을 미칠 수 있습니다. - 30 년 이상 안정적으로 작동합니다.
- 엄청나게 쉽게 구현할 수 있고 견고 함 : 프로세스가 어떤 세상은 끝나지 잘못 할 수있는 (거의) 아무것도 없습니다.
- "천둥 무리"에 매우 취약합니다.
poll
/select
- 다소 동일한 것의 두 가지 유형 (BSD 대 시스템 V).
- 다소 오래되고 느리고 다소 어색한 사용이지만 지원하지 않는 플랫폼은 없습니다.
- 설명자 집합에서 "무언가 발생"할 때까지 기다립니다.
- 하나의 단일 / 프로세스가 한 번에 많은 요청을 처리 할 수 있습니다.
- 멀티 코어 사용이 없습니다.
- 기다릴 때마다 사용자의 설명자 목록을 복사해야합니다. 설명자에 대한 선형 검색을 수행해야합니다. 이 효과를 제한합니다.
- "수천"으로 잘 확장되지 않는 언어 (사실 대부분의 시스템에서 약 1024 개 또는 일부 시스템에서 64 개까지의 하드 제한).
- 어쨌든 12 개의 설명이 자만 처리하거나 (성능 문제가 없음) 더 나은 것이없는 플랫폼을 지원해야하는 경우 이식이 가능하기 때문에. 달리 사용하지 않습니다.
- 개념적으로 서버는 복잡한 서버보다 조금 더 복잡해집니다. 이제 각 연결에 대해 많은 연결과 상태 머신을 유지해야하고 요청이 들어올 때마다 다중화하고 부분적인 요청을 조합해야합니다. 간단한 분기 서버는 소켓에 대해 알고 (2 개, 소켓 소켓에 대해 알고 있습니다.), 원하는 것을 얻거나 연결이 반쯤 닫힐 때까지 읽은 다음 원하는 것을 작성합니다. 차단 또는 준비 상태에 대해 걱정하지 않으셔도됩니다. 이는 다른 프로세스의 문제입니다.
epoll
- Linux 전용입니다.
- 비용이 많이 사용되는 수정과 효율적인 대기의 개념 :
- 설명자가 추가 될 때 설명자에 대한 정보를 추가 할 때 복사합니다 (
epoll_ctl
).- 이것은 일반적으로 드물게 발생하는 일 입니다.
- 않습니다 되지 이벤트를 기다릴 때 (커널 공간에 데이터를 복사 할 필요
epoll_wait
)- 이것은 일반적으로 매우 자주 발생합니다 .
- 설명 자의 대기 큐에 대기자 (또는 그 epoll 구조)를 추가합니다.
- 그것은 대기자에게 직접 신호를 보냅니다.
poll
작동 방식의 반대 방식- O (n) 대신 설명자 수와 관련하여 작은 k (매우 빠름)가있는 O (1)
- 설명자가 추가 될 때 설명자에 대한 정보를 추가 할 때 복사합니다 (
timerfd
및eventfd
(놀라운 타이머 해상도 및 정확도) 와 매우 잘 작동 합니다.- 와 잘 작동
signalfd
하여 신호의 어색한 처리를 제거하여 매우 우아한 방식으로 처리 제어 흐름의 일부로 만듭니다. - epoll 인스턴스는 다른 epoll 인스턴스를 재귀 적으로 호스팅 할 수 있습니다.
- 이 프로그래밍 모델의 가정 :
- 대부분의 디스크립터는 대부분의 경우 유휴 상태이며, 실제로 몇 가지 디스크립터에서 거의 발생하지 않습니다 (예 : "데이터 수신", "연결 종료").
- 대부분의 경우 세트에서 설명을 추가 / 제거하고 싶지 않습니다.
- 대부분의 경우, 당신은 어떤 일이 일어나기를 기다리고 있습니다.
- 몇 가지 사소한 함정 :
- 레벨 트리거 epoll은 대기중인 모든 스피커를 사용하는 순진한 방법은 쓸모가 없습니다. 우선 TCP 서버의 경우, 어쨌든 부분 요청이 먼저 어셈블되어야하기 때문에 큰 문제가 아니 순진한 다중 구현은 어느 쪽도 수행하지 않습니다.
- 파일 읽기 / 쓰기에서 예상대로 작동하지 않습니다 ( "항상 준비 됨").
- 최근까지 AIO와 함께 사용할 수
eventfd
없지만 이제는 통해 가능 하지만 (현재까지) 문서화되지 않은 기능이 필요합니다. - 의 가정이 위 사실 이 아닌 경우는 epoll 비효율적 일 수은 있으며
poll
동일하거나 더 나은 성능을 발휘할 수 있습니다 . epoll
"마법"을 수행 할 수 없습니다. 즉, 발생 하는 이벤트 수와 관련하여 여전히 반드시 O (N)입니다 .- 그러나
epoll
새로운recvmmsg
syscall은 한 번에 여러 개의 준비 알림을 반환하기 때문에 잘 작동합니다 (사용 가능한만큼 많이, 지정으로하는 것까지maxevents
). 이를 통해 바쁜 서버에서 하나의 시스템 콜로 15 개의 EPOLLIN 알림을 수신하고 두 번째 시스템 콜로 해당 15 개의 메시지를 읽을 수 있습니다 (시스템 콜 93 % 감소!). 하나의 불행히도recvmmsg
호출 에, 대한 모든 작업 은 동일한 소켓을 참조하므로 UDP 기반 서비스에 대부분 유용합니다 (TCP 경우의recvmmsmsg
항목 당 소켓 설명자를 취하는 일종의 콜 이 있어야합니다 !). - 설명 자는 항상 비 차단으로 설정되어야 하며 보고서 준비 및 후속 읽기 (또는 쓰기)가 여전히 차단 되는 예외적 인 상황이 있기 때문에
EAGAIN
사용 중에도 확인해야합니다 . 이것은 또한의 경우입니다 / (이것은 아마도 수정되었습니다하지만) 일부 커널에.epoll
epoll
poll
select
- A를 순진 구현, 느린 보낸 사람의 굶주림이 가능합니다.
EAGAIN
알림을 받으면 맹목적으로 읽기 until 이 반환되면 느린 발신자는 완전히 굶주 리면서 빠른 발신자로부터 새로운 수신 데이터를 무기한 읽을 수 있습니다 (데이터가 충분히 빠르게 수신EAGAIN
되는 한 꽤 오랫동안 보지 못할 수 있습니다 ! ).poll
/select
에 동일한 방식으로 적용됩니다 . - Edge-triggered 모드는 문서 (맨 페이지와 TLPI 모두)가 모호하고 ( "아마", "해야한다", "할 수 있습니다") 때때로 작동에 대해 오해를 불러 일으키기 때문에 일부 상황에서 몇 가지 단점과 예기치 않은 동작이 있습니다.
문서에 따르면 하나의 epoll에서 대기중인 여러 스레드가 모두 신호를받습니다. 또한 알림은에 대한 마지막 호출epoll_wait
이후 (또는 이전 호출이없는 경우 디스크립터가 열린 이후) IO 활동이 발생했는지 여부를 알려줍니다 .
에지 트리거 모드에서 진정한, 관찰 동작은 훨씬 더 가까이 "는 깨어하는 첫번째 호출 한 스레드를epoll_wait
IO 활동 이후 일어난 것을 신호, 사람이 마지막으로 통화 중epoll_wait
또는읽기 / 쓰기 기술자에 대한 기능, 그 이후에만 다시 준비 상태를보고 다음 스레드가 호출 또는 이미 차단에epoll_wait
이후에 일어나는 모든 작업, 사람이 기술자의 기능 "읽기 (또는 쓰기)의 불렀다. 그것을 종류의 차종 감각의 , 너무 ... 문서에서 제안하는 것과 정확히 일치하지 않습니다.
kqueue
- BSD analogon to
epoll
, 다른 사용법, 유사한 효과. - Mac OS X에서도 작동합니다.
- 더 빠르다는 소문이 있습니다 (나는 그것을 사용한 적이 없으므로 그것이 사실인지 알 수 없습니다).
- 이벤트를 등록하고 단일 syscall에서 결과 집합을 반환합니다.
- BSD analogon to
- IO 완료 포트
- Windows 용 Epoll 또는 스테로이드에 대한 epoll.
- 어떤 방식 으로든 대기 가능하거나 경고 가능한 모든 항목 (소켓, 대기 가능 타이머, 파일 작업, 스레드, 프로세스) 과 원활하게 작동합니다.
- Microsoft가 Windows에서 한 가지를 올바르게 잡았다면 완료 포트입니다.
- 스레드 수에 관계없이 즉시 사용 가능
- 천둥 무리 없음
- LIFO 순서로 스레드를 하나씩 깨 웁니다.
- 캐시를 따뜻하게 유지하고 컨텍스트 전환을 최소화합니다.
- 기계의 프로세서 수를 존중하거나 원하는 수의 작업자를 제공합니다.
- 애플리케이션이 이벤트를 게시 할 수 있도록 허용하여 매우 쉽고 안전하며 효율적인 병렬 작업 대기열 구현을 제공합니다 (내 시스템에서 초당 500,000 개 이상의 작업을 예약).
- 사소한 단점 : 일단 추가 된 파일 설명자를 쉽게 제거하지 않습니다 (닫았다가 다시 열어야 함).
프레임 워크
libevent -2.0 버전은 Windows에서 완료 포트도 지원합니다.
ASIO- 프로젝트에서 Boost를 사용하는 경우 더 이상 보지 마십시오. 이미 boost-asio로 사용할 수 있습니다.
간단한 / 기본 자습서에 대한 제안 사항이 있습니까?
위에 나열된 프레임 워크는 광범위한 문서와 함께 제공됩니다. Linux 문서 와 MSDN은 epoll 및 완료 포트를 광범위하게 설명합니다.
epoll 사용을위한 미니 자습서 :
int my_epoll = epoll_create(0); // argument is ignored nowadays
epoll_event e;
e.fd = some_socket_fd; // this can in fact be anything you like
epoll_ctl(my_epoll, EPOLL_CTL_ADD, some_socket_fd, &e);
...
epoll_event evt[10]; // or whatever number
for(...)
if((num = epoll_wait(my_epoll, evt, 10, -1)) > 0)
do_something();
IO 완료 포트에 대한 미니 자습서 (다른 매개 변수를 사용하여 CreateIoCompletionPort를 두 번 호출) :
HANDLE iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0); // equals epoll_create
CreateIoCompletionPort(mySocketHandle, iocp, 0, 0); // equals epoll_ctl(EPOLL_CTL_ADD)
OVERLAPPED o;
for(...)
if(GetQueuedCompletionStatus(iocp, &number_bytes, &key, &o, INFINITE)) // equals epoll_wait()
do_something();
(이 미니 튜 트는 모든 종류의 오류 검사를 생략하고 오타를 만들지 않았기를 바라지 만 대부분의 경우 약간의 아이디어를 제공하는 것이 좋습니다.)
편집 :
완료 포트 (Windows)는 개념적으로 epoll (또는 kqueue)과 반대로 작동합니다. 자신의 이름이 암시 하듯이 그들은 신호를 완료 하지 준비 . 즉, 비동기 요청을 실행하고 나중에 완료되었다는 메시지가 표시 될 때까지 잊어 버립니다 (성공적이든 그다지 성공적이지 않았 든 "즉시 완료"라는 예외적 인 경우도 있음).
epoll을 사용하면 "일부 데이터"(아마도 1 바이트 정도)가 도착하여 사용 가능하거나 충분한 버퍼 공간이 있다는 알림을받을 때까지 차단하여 차단하지 않고 쓰기 작업을 수행 할 수 있습니다. 그래야만 실제 작업을 시작합니다. 그러면 차단되지 않을 것입니다 (예상하는 것 외에는 이에 대한 엄격한 보장이 없습니다. 따라서 설명자를 비 차단으로 설정하고 EAGAIN [EAGAIN 및 EWOULDBLOCK]을 확인하는 것이 좋습니다. 소켓의 경우, 오 기쁨, 표준은 두 가지 다른 오류 값을 허용하기 때문에]).
참고 URL : https://stackoverflow.com/questions/4093185/whats-the-difference-between-epoll-poll-threadpool
'ProgramingTip' 카테고리의 다른 글
UIAppearance 프록시를 통해 어떤 속성을 접근 할 수 있습니까? (0) | 2020.10.20 |
---|---|
버튼에 그림자를 제공하는 방법 (0) | 2020.10.20 |
C #에서 Null 매개 변수 검사 (0) | 2020.10.20 |
점선 (0) | 2020.10.20 |
PostgreSQL 서버가 중지되지 않았습니다 (0) | 2020.10.20 |