asio의 설명서를 읽으면서 완료 핸들러가 io_service의 io.run()
메서드를 호출 한 스레드 중 하나에 의해 호출된다는 것은 분명합니다. 그러나 나에게 명확하지 않은 것은 읽기/쓰기 비동기 메소드가 발생하는 스레드입니다. 내가 메서드라고 부르는 스레드입니까, 아니면 io.run()
메서드를 호출 한 스레드 중 하나입니까? 또는 마지막으로 라이브러리가 장면 뒤에서 또 다른 스레드를 만들고 작업을 수행합니까?스레드 비동기 작업 수행
답변
예를 들어 일부 데이터를 원격 파트너 비동기로 보내려합니다.
boost::asio::async_write(_socket, boost::asio::buffer(msg.data(), msg.size()),
std::bind(&Socket::WriteHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
//Where 'this' is the class Socket
그 전에 아마도 ioService.run()
이라는 스레드를 만들었을 것입니다. async_write
함수는 소켓을 만드는 데 사용한 것과 동일한 ioService
을 사용합니다. 의 큐에 쓰기 작업을 실행하고 에서 이미 제시 한대로 ioService
이 실행되는 스레드에서 처리기 - 을 실행합니다.
그게 내가 의심했던 것이다. 그러나, 나는 이것을 boost 문서에서 명시 적으로 보지 않았기 때문에 어떤 가정도하고 싶지 않았다. –
시작하는 async_*
기능 내에서 입출력 작업이 시도됩니다. 작업의 완료 조건이 충족되거나 오류가 발생하면 작업이 완료되고 완료 핸들러가 io_service
에 게시됩니다. 그렇지 않으면 작업이 완료되지 않으며 io_service
의 기능 poll()
, poll_one()
, run()
또는 run_one()
을 실행하는 응용 프로그램 스레드가 기본 I/O 작업을 수행하는 io_service
에 대기열에 포함됩니다. 두 경우 모두 완료 핸들러는 io_service
을 처리하는 스레드에 의해 호출됩니다.
는 무관하게 비동기 동작을 즉시 아닌지 완료 여부 핸들러가이 함수 내에서 호출되지 않는다 :
async_write()
문서는 비동기 작업이 즉시 완료 될 수 있다는 것을 지적한다. 핸들러 호출은boost::asio::io_service::post()
을 사용하는 것과 동일한 방식으로 수행됩니다.
이 문제는 또한 Requirements on Asynchronous Operations 문서에 기록됩니다 :
- 바운드를 구축 : 비동기 작업이 완료되면
, 운영을위한 핸들러가 호출되는 경우와 같은 처리기에 대한 완료 처리기
bch
- 지연된 호출에 대한 처리기를 예약하기 위해
ios.post(bch)
을 호출하려면 ...
이는 비동기 작업이 즉시 완료 되더라도 시작 함수 내에서 직접 핸들러를 호출하면 안된다는 것을 의미합니다. 여기
는 완전한 예를 demonstrating이 동작입니다. 그 안에
socket1
과
socket2
이 연결되어 있습니다. 처음에는
socket2
에 데이터가 없습니다.당신이 스레드 로컬 상태 알고 싶어 차단 일부 작업의 경우, 또는 때문에 알고 싶어하기 때문에
#include <boost/asio.hpp>
constexpr auto noop = [](auto&& ...){};
int main()
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
// Create all I/O objects.
tcp::acceptor acceptor{io_service, {{}, 0}};
tcp::socket socket1{io_service};
tcp::socket socket2{io_service};
// Connect sockets.
acceptor.async_accept(socket1, noop);
socket2.async_connect(acceptor.local_endpoint(), noop);
io_service.run();
io_service.reset();
// Verify socket2 has no data.
assert(0 == socket2.available());
// Initiate an asynchronous write. However, do not run
// the `io_service`.
std::string data{"example"};
async_write(socket1, boost::asio::buffer(data), noop);
// Verify socket2 has data.
assert(0 < socket2.available());
}
이인가 그러나,
async_write(socket1, ...)
를 호출 한 후,socket2
는io_service
가 실행되지 않은 경우에도 데이터가 변수가 있거나 다른 목적이 있습니까? – Yakk중요한 응용 프로그램을 개발 중이므로 응용 프로그램이 실행중인 스레드에 시간을 낭비 할 여유가 없습니다. 나는 람다가 io_service를 써서 run() 메서드를 호출 한 스레드 중 하나에서 작업을 작성하도록 게시 할 수 있음을 알고있다. 그러나 라이브러리 자체가 쓰기 작업을 수행하기 위해 다른 스레드를 만드는 경우 io_service에 게시 할 필요가 없습니다. –
[플랫폼 별 구현 참고 사항] (http://www.boost.org/doc/libs/1_65_1/doc/html/boost_asio/overview/implementation.html) 문서는 모든 내부 스레드의 생성과 용도에 대해 설명합니다. 내부 쓰레드는 쓰기 조작을 서비스하지 않습니다. –