[CPP] Boost - asio

윤동환·2023년 5월 10일
0

CPP

목록 보기
1/4
post-thumbnail

asio

Boost.Asio는 프로그램이 스레드 및 명시적 잠금을 기반으로 하는 동시성 모델을 사용하지 않고도 이러한 장기 실행 작업을 관리할 수 있는 도구를 제공합니다.

Boost.Asio 라이브러리는 네트워킹과 같은 운영 체제 기능에 대한 액세스가 종종 필요한 시스템 프로그래밍에 C++를 사용하는 프로그래머를 위한 것입니다.

연결 작업 동작 원리

동기식


프로그램에는
boost::asio::io_context 개체, boost::asio::thread_pool 개체 또는 boost::asio::system_context와 같은 I/O 실행 컨텍스트가 하나 이상 있습니다.
이 I/O 실행 컨텍스트는 운영 체제의 I/O 서비스에 대한 프로그램의 링크를 나타냅니다.

boost::asio::io_context io_context;

I/O 작업을 수행하려면 프로그램에 TCP 소켓과 같은 I/O 개체가 필요합니다 .

boost::asio::ip::tcp::socket socket(io_context);

동작 순서

동기식 연결 작업이 수행되면 다음과 같은 일련의 이벤트가 발생합니다.
1. 프로그램은 I/O 객체를 호출하여 연결작업(connet)를 시작합니다.

socket.connect(server_endpoint);
  1. I/O 객체는 I/O 실행 컨텍스트로 요청을 전달합니다.
  2. I/O 실행 컨텍스트는 연결 작업을 위해 OS를 호출합니다.
  3. OS는 작업의 결과를 I/O 실행 컨텍스트로 반환합니다.
  4. I/O 실행 컨텍스트는 작업으로 인한 모든 오류 결과를 boost::system::error_code 유형의 개체로 변환합니다.
  5. I/O 객체는 작업이 실패했다면, boost::system::system_error 타입을 던집니다.
    만약 작업을 시작하는 코드가 아래와 같이 작성되었다면
boost::system::error_code ec;
socket.connect(server_endpoint, ec);

error_code 변수 ec은 작업 결과로 설정되며 예외가 발생하지 않습니다.

비동기식

동작 순서

  1. 프로그램은 I/O 객체라 불리는 것으로 연결작업을 시작해야 합니다.
socket.async_connect(server_endpoint, your_completion_handler);

your_completion_handler는 signature 함수 또는 함수 객체입니다.

void your_completion_handler(const boost::system::error_code& ec);

signature
함수 시그니처란 함수의 원형에 명시되는 매개변수 리스트를 가리킵니다.

ex) void your_completion_handler(const boost::system::error_code& ec);
your_completion_handler의 시그니처 : void(const boost::system::error_code&)

정확한 signature는 실행중인 비동기 작업의 의존에 필수적입니다.
참조문서는 각 작업에 적합한 형식을 나타냅니다.

  1. I/O객체는 I/O 실행 컨텍스트에 요청사항을 전달합니다.
  2. I/O 실행 컨텍스트는 OS에 비동기 연결을 시작하라는 signal을 보냅니다.
  3. OS는 I/O 실행 컨텍스트에서 가져갈 수 있는 큐에 결과를 배치하여 연결 작업이 완료되었음을 나타냅니다.
  4. io_context를 I/O 실행 컨텍스트로 사용하는 경우 결과를 검색하려면 프로그램에서 io_context::run()(또는 유사한 io_context 멤버 함수 중 하나)을 호출해야 합니다.

    io_context::run()에 대한 호출은 완료되지 않은 비동기 작업이 있는 동안 차단되므로 일반적으로 첫 번째 비동기 작업을 시작하자마자 호출합니다.

  5. io_context::run()에 대한 호출 내부에서 I/O 실행 컨텍스트는 작업 결과를 대기열에서 빼고 error_code로 변환한 다음 your_completion_handler로 전달합니다.

예제

  1. Timer.1 - Using a timer synchronously
#include <iostream>
#include <boost/asio.hpp>

int main()
{
  boost::asio::io_context io;
  
  boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5));
  
  t.wait();
  
  std::cout << "Hello, world!" << std::endl;

  return 0;
}
  • asio를 사용하는 모든 프로그램에는 io_context 또는 thread_pool 개체 와 같은 하나 이상의 I/O 실행 컨텍스트가 있어야 합니다 . I/O 실행 컨텍스트는 I/O 기능에 대한 액세스를 제공합니다. 메인 함수에서 가장 먼저 io_context 유형의 객체를 선언합니다 .
  • 다음으로 boost::asio::steady_timer 유형의 객체를 선언합니다. I/O 기능(또는 이 경우 타이머 기능)을 제공하는 핵심 asio 클래스는 항상 첫 번째 생성자 인수로 실행기 또는 실행 컨텍스트(예: io_context )에 대한 참조를 사용합니다. 생성자에 대한 두 번째 인수는 타이머가 지금부터 5초 후에 만료되도록 설정합니다.
  • 이 간단한 예제에서는 타이머에서 차단 대기를 수행합니다. 즉, steady_timer::wait() 에 대한 호출 은 타이머가 생성된 후 5초(즉, 대기가 시작된 시점이 아님)가 만료될 때까지 반환되지 않습니다.
    타이머는 항상 "만료됨" 또는 "만료되지 않음"의 두 가지 상태 중 하나입니다. steady_timer ::wait() 함수가 만료된 타이머에서 호출되면 즉시 반환됩니다.
  • "Hello, world!"마지막으로 타이머가 만료되었을 때 표시하는 필수 메시지를 인쇄합니다 .

Reference

https://www.boost.org/doc/libs/
https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio/overview/basics.html

profile
모르면 공부하고 알게되면 공유하는 개발자

0개의 댓글