답변:
Boost.Asio 는 네트워킹에 중점을 둔 C ++ 라이브러리이지만 비동기 I / O 기능이 다른 리소스로 확장되었습니다. 또한 Boost.Asio가 Boost 라이브러리의 일부인 경우 다른 Boost 라이브러리와 중복되지 않도록 범위가 약간 좁아집니다. 예를 들어 Boost.Thread가 이미 스레드 추상화를 제공하므로 Boost.Asio는 스레드 추상화를 제공하지 않습니다 .
반면에 libuv 는 Node.js 의 플랫폼 레이어로 설계된 C 라이브러리입니다 . Windows의 IOCP , macOS의 kqueue 및 Linux의 epoll 에 대한 추상화를 제공합니다 . 또한 스레드, 스레드 풀 및 스레드 간 통신과 같은 추상화 및 기능을 포함하여 범위가 약간 증가한 것처럼 보입니다.
핵심적으로 각 라이브러리는 이벤트 루프 및 비동기 I / O 기능을 제공합니다. 타이머, 소켓 및 비동기 작업과 같은 일부 기본 기능에 대해서는 중복됩니다. libuv는 더 넓은 범위를 가지고 있으며 스레드 및 동기화 추상화, 동기 및 비동기 파일 시스템 작업, 프로세스 관리 등과 같은 추가 기능을 제공합니다. 반대로 Boost.Asio의 원래 네트워킹 포커스 표면은 풍부한 네트워크 관련 세트를 제공하므로 ICMP, SSL, 동기식 차단 및 비 차단 작업과 같은 기능 및 줄 바꿈이 수신 될 때까지 스트림에서 읽는 것을 포함하여 일반적인 작업에 대한 상위 수준 작업.
다음은 몇 가지 주요 기능에 대한 간단한 비교입니다. Boost.Asio를 사용하는 개발자는 종종 다른 Boost 라이브러리를 사용할 수 있으므로 추가 Boost 라이브러리가 직접 제공되거나 구현하기가 쉽지 않은 경우 추가 Boost 라이브러리를 고려하기로 결정했습니다.
libuv 부스트 이벤트 루프 : 예 Asio 스레드 풀 : 예 Asio + 스레드 스레딩 : 스레드 : 예 스레드 동기화 : 예 스레드 파일 시스템 작업 : 동기식 : 예 FileSystem 비동기 : 예 Asio + 파일 시스템 타이머 : 예 Asio 분산 형 / 수집 I / O [1] : 아시오 없음 네트워킹 : ICMP : 아시오 없음 DNS 확인 : 비동기 전용 Asio SSL : 아시오 없음 TCP : 비동기 전용 Asio UDP : 비동기 전용 Asio 신호: 처리 : 예 Asio 발송 : 예 아니요 IPC : 유닉스 도메인 소켓 : 예 Windows 명명 된 파이프 : 예 Asio 공정 관리: 분리 : 예 프로세스 I / O 파이프 : 예 프로세스 산란 : 예 프로세스 시스템 검색어 : CPU : 예 아니요 네트워크 인터페이스 : 예 아니요 직렬 포트 : 아니요 예 TTY : 예 아니요 공유 라이브러리 로딩 : 예 확장 [2]
1. 분산 형 / I / O를 수집합니다 .
2. Boost.Extension 은 Boost에 대한 검토를 위해 제출되지 않았습니다. 여기 에 언급 된 바와 같이 저자는 완성 된 것으로 간주합니다.
libuv와 Boost.Asio는 모두 이벤트 루프를 제공하지만 둘 사이에는 약간의 차이점이 있습니다.
uv_default_loop()
새 루프 ( uv_loop_new()
)를 작성하지 않고 기본 루프 ( )를 사용할 때주의를 기울여야합니다 .io_service
여러 스레드를 실행할 수있는 자체 루프입니다. 이 Boost.Asio 는 일부 성능을 희생하면서 내부 잠금 을 수행 합니다 . Boost.Asio의 개정 이력 은 잠금을 최소화하기 위해 몇 가지 성능이 개선되었음을 나타냅니다.uv_queue_work
. 스레드 풀 크기는 환경 변수를 통해 구성 할 수 있습니다 UV_THREADPOOL_SIZE
. 작업은 이벤트 루프 외부와 스레드 풀 내에서 실행됩니다. 작업이 완료되면 완료 핸들러가 이벤트 루프 내에서 실행되도록 큐에 대기됩니다.io_service
하여 하나의 기능을 쉽게 수행 할 수 있습니다 . 에서 볼 수 있듯이 이것은 사용자 스레드 관리와 행동의 책임을 배치 이 예.io_service
run
EAGAIN
EWOULDBLOCK
kill
및 신호 처리 기능을 제공합니다 .uv_signal_t
uv_signal_*
kill
, 그러나 그것은 signal_set
신호 처리를 제공합니다.uv_pipe_t
유형을 통해 추상화 합니다.local::stream_protocol::socket
하거나 local::datagram_protocol::socket
,하고 windows::stream_handle
.API 만 언어에 따라 다르지만 다음과 같은 몇 가지 주요 차이점이 있습니다.
Boost.Asio에는 작업과 처리기간에 일대일 매핑이 있습니다. 예를 들어, 각 async_write
작업은 WriteHandler를 한 번 호출합니다 . 이것은 많은 libuv 작업 및 처리기에 적용됩니다. 그러나 libuv uv_async_send
는 다 대일 매핑을 지원합니다. 여러 번의 uv_async_send
호출로 인해 uv_async_cb 가 한 번 호출 될 수 있습니다 .
스트림 / UDP에서 읽기, 신호 처리 또는 타이머 대기와 같은 작업을 처리 할 때 Boost.Asio의 비동기식 호출 체인은 좀 더 명확합니다. libuv를 사용하면 특정 이벤트에 대한 관심을 지정하기 위해 감시자가 작성됩니다. 그런 다음 콜백이 제공되는 감시자에 대해 루프가 시작됩니다. 관심 이벤트가 수신되면 콜백이 호출됩니다. 반면, Boost.Asio는 응용 프로그램이 이벤트 처리에 관심이있을 때마다 작업을 발행해야합니다.
이러한 차이점을 설명하기 위해 다음은 Boost.Asio가있는 비동기 읽기 루프입니다. 여기서 async_receive
호출이 여러 번 발행됩니다.
void start()
{
socket.async_receive( buffer, handle_read ); ----.
} |
.----------------------------------------------'
| .---------------------------------------.
V V |
void handle_read( ... ) |
{ |
std::cout << "got data" << std::endl; |
socket.async_receive( buffer, handle_read ); --'
}
그리고 여기 libuv와 동일한 예가 있습니다. 여기 handle_read
에서 감시자는 소켓에 데이터가 있음을 관찰 할 때마다 호출됩니다.
uv_read_start( socket, alloc_buffer, handle_read ); --.
|
.-------------------------------------------------'
|
V
void handle_read( ... )
{
fprintf( stdout, "got data\n" );
}
Boost.Asio의 비동기 호출 체인과 libuv의 감시자 때문에 메모리 할당이 종종 다른 시간에 발생합니다. 감시자는 libuv는 처리해야 할 메모리가 필요한 이벤트를 수신 할 때까지 할당을 연기합니다. 할당은 사용자 콜백을 통해 이루어지며 libuv 내부에서 호출되며 응용 프로그램의 할당 취소 책임을 연기합니다. 반면, Boost.Asio 작업의 많은 경우 buffer
for 와 같은 비동기 작업을 수행하기 전에 메모리를 할당해야 합니다 async_read
. Boost.Asio는 null_buffers
이벤트를 수신하는 데 사용할 수있는을 제공 하여 메모리가 필요할 때까지 응용 프로그램이 메모리 할당을 연기 할 수 있도록합니다.
이 메모리 할당 차이는 bind->listen->accept
루프 내에서도 나타납니다 . libuv를 uv_listen
사용하면 연결을 수락 할 준비가되면 사용자 콜백을 호출하는 이벤트 루프를 만듭니다. 이를 통해 응용 프로그램은 연결을 시도 할 때까지 클라이언트 할당을 연기 할 수 있습니다. 반면에 Boost.Asio는의 listen
상태 만 변경합니다 acceptor
. async_accept
연결 이벤트를 수신하고, 동료를 필요가 호출되기 전에 할당 할 수 있습니다.
불행히도 libuv와 Boost.Asio를 비교할 구체적인 벤치 마크 번호는 없습니다. 그러나 실시간 및 거의 실시간 응용 프로그램에서 라이브러리를 사용하여 비슷한 성능을 관찰했습니다. 어려운 숫자가 필요한 경우 libuv의 벤치 마크 테스트 가 시작점이 될 수 있습니다.
또한 실제 병목 현상을 식별하기 위해 프로파일 링을 수행해야하지만 메모리 할당에주의하십시오. libuv의 경우 메모리 할당 전략은 기본적으로 할당 자 콜백으로 제한됩니다. 반면 Boost.Asio의 API는 할당 자 콜백을 허용하지 않고 대신 할당 전략을 애플리케이션에 푸시합니다. 그러나 Boost.Asio의 핸들러 / 콜백은 복사, 할당 및 할당 해제 될 수 있습니다. Boost.Asio는 애플리케이션이 핸들러에 대한 메모리 할당 전략을 구현하기 위해 사용자 정의 메모리 할당 기능 을 제공 할 수 있도록합니다 .
Asio의 개발은 2004 년 10 월 이상으로 거슬러 올라가며, 20 일 동료 검토를 거친 후 2006 년 3 월 22 일 부스트 1.35에 채택되었습니다. 또한 TR2 용 네트워킹 라이브러리 제안을 위한 참조 구현 및 API 역할을했습니다 . Boost.Asio는 유용성이 사용자마다 다르지만 상당히 많은 양의 문서 를 가지고 있습니다.
API는 또한 상당히 일관된 느낌을 가지고 있습니다. 또한 비동기 작업은 작업 이름에 명시 적입니다. 예를 들어, accept
동기식 차단이며 async_accept
비동기식입니다. API는 일반적인 I / O 작업에 대한 무료 기능 (예 : a \r\n
을 읽을 때까지 스트림에서 읽는 기능)을 제공합니다 . ip::address_v4::any()
의 "모든 인터페이스"주소를 나타내는 것과 같은 일부 네트워크 특정 정보를 숨기도록주의를 기울 였습니다 0.0.0.0
.
마지막으로 Boost 1.47+는 C ++ 11 지원뿐만 아니라 디버깅 할 때 유용 할 수있는 핸들러 추적 기능을 제공 합니다 .
github 그래프를 기반으로 Node.js의 개발 날짜는 FEB-2009 이상으로 , libuv의 개발 날짜는 MAR-2011으로되어 있습니다. uvbook는 libuv 도입을위한 좋은 장소입니다. API 설명서는 여기에 있습니다 .
전반적으로 API는 상당히 일관되고 사용하기 쉽습니다. 혼란의 원인이 될 수있는 예외 uv_tcp_listen
는 감시자 루프 를 만드는 것입니다. 이는 일반적으로가 다른 관찰자 다르다 uv_*_start
및 uv_*_stop
워처 루프의 수명을 제어하는 기능 쌍. 또한 일부 uv_fs_*
연산에는 적절한 양의 인수가 있습니다 (최대 7 개). 콜백 (마지막 인수)이있을 때 동기 및 비동기 동작이 결정되면 동기 동작의 가시성이 줄어들 수 있습니다.
마지막으로 libuv 커밋 히스토리를 간략히 살펴보면 개발자가 매우 활동적이라는 것을 알 수 있습니다.
uv_async_send
호출을 누적 하고 단일 콜백으로 모두 처리 할 수 있습니다. 여기에 문서화되어 있습니다 . 또한 모두 감사합니다.
확인. 두 라이브러리를 모두 사용한 경험이 있으며 일부 내용을 정리할 수 있습니다.
첫째, 개념적 관점에서 볼 때 이러한 라이브러리는 디자인이 상당히 다릅니다. 규모가 다르기 때문에 아키텍처가 다릅니다. Boost.Asio는 TCP / UDP / ICMP 프로토콜, POSIX, SSL 등과 함께 사용하기위한 대규모 네트워킹 라이브러리입니다. Libuv는 주로 Node.js 용 IOCP의 크로스 플랫폼 추상화를위한 계층입니다 . 따라서 libuv는 기능적으로 Boost.Asio의 하위 집합입니다 (일반적인 기능은 TCP / UDP 소켓 스레드, 타이머 만 해당). 이 경우 몇 가지 기준 만 사용하여 이러한 라이브러리를 비교할 수 있습니다.
새로운 C ++ 기능과의 통합 : Asio가 더 우수합니다 (Asio 1.51은 C ++ 11 비동기 모델을 광범위하게 사용하고 의미론을 이동하며 가변적 템플릿을 사용합니다). 성숙도와 관련하여 Asio는 문서화가 우수한보다 안정적이고 성숙한 프로젝트입니다 (libuv와 비교할 경우) 헤더 설명), 인터넷을 통한 많은 정보 (비디오 토크, 블로그 : http://www.gamedev.net/blog/950/entry-2249317-a-guide-to-getting-started-with-boostasio?pg = 1 등) 및 심지어 책 (전문가는 아니지만 http://en.highscore.de/cpp/boost/index.html ) Libuv는 단 하나의 온라인 서적을 보유하고 있습니다 ( http://nikhilm.github.com/uvbook/index.html).여러 비디오 대화를 통해 모든 비밀을 알기가 어려울 것입니다 (이 라이브러리에는 많은 비밀이 있습니다). 기능에 대한 자세한 설명은 아래 내 의견을 참조하십시오.
결론적으로, 나는 그것이 당신의 목적, 프로젝트 및 구체적으로 무엇을하고자하는지에 달려 있다고 말해야합니다.
한 가지 큰 차이점은 Asio (Christopher Kohlhoff)의 저자가 C ++ 표준 라이브러리에 포함시키기 위해 자신의 라이브러리를 정리하고 있다는 것입니다. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2175 .pdf 및 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4370.html
이식성 상태 추가 :이 답변을 게시 할 때 본인의 시도에 따라 :