본문 바로가기

C++

C++ 면접 질문) "boost asio를 사용하여 어떻게 event-driven architecture를 구현하셨나요?"

boost asio 소개:

- boost 비동기 지원 라이브러리

 

io_context 소개:

- 기본적으로 job queue를 관리하고 실행하는 단위라고 보면 됨

- post, dispatch 함수를 통해 job 등록이 가능

- 네트워크 소켓, 타이머, 파일 I/O 등 시스템 I/O 처리에 대한 callback 이 job인 경우 I/O 처리가 완료된 시점 job 등록됨

- 즉, OS I/O 멀티플렉싱 활용 비동기 처리 가능: 특정 I/O 작업에 대한 callback 등록 필요

  - OS I/O 멀티플렉싱: epoll, kqueue 등 을 사용하여 소켓에 데이터가 오거나 타이머가 만료된 이벤트를 감지

 

io_context 특징:

- 내부적으로 job queue 관리

  - job은 FIFO 순으로 처리됨

- job이 비동기 처리를 지원하면, 비동기 방식으로 처리함

  - I/O 멀티플렉싱 API 를 활용하여 I/O 작업 완료를 감지 시 job queue에 핸들러 실행 job 추가 

 

웹소켓 통신 비동기 처리:

- 예시:

class WebSocketClient : public std::enable_shared_from_this<WebSocketClient> {
public:
    WebSocketClient(asio::io_context& io_context, const std::string& host, const std::string& port)
        : resolver_(asio::make_strand(io_context)),
          ws_(asio::make_strand(io_context)),
          host_(host),
          port_(port) {}
private:
    tcp::resolver resolver_;
    websocket::stream<beast::tcp_stream> ws_;
}

// resolver_, ws_ 생성 시 인자로 io_context 넣음

ws_.async_read(buffer_,
  [this, self](beast::error_code ec, std::size_t bytes_transferred) {
    // callback 로직
  }
);

// async_read 호출 시 자동으로 io_context 가 관리하는 job queue 에 관리됨.
// websocket read 완료 시 job queue 에 callback 실행 job 추가
// websocket read 완료를 알기 위해서 io_context 는 epoll 감지 대상을 websocket stream 내부 TCP socket file descriptor 를 대상으로 함

 

멀티쓰레딩 방법:

- 쓰레드풀: 쓰레드간 io_context 객체 공유

- strand 활용 직렬화 가능

 

io_context 활용 사용자 정의 file descriptor async_read:

- 예시:

// device fd 획득

const char* device_path = "/dev/input/event0";
int fd = open(device_path, O_RDONLY | O_NONBLOCK);

// boost asio stream 객체로 정의

asio::posix::stream_descriptor stream(io_context, fd);

// stream 객체에 대해서 async_read 진행 (epoll이 완료되면 callback이 job queue에 추가됨)

stream.async_read_some(boost::asio::buffer(buffer), [&](const boost::system::error_code& ec, std::size_t bytes_transferred) {
    // callback
  }
);

 

io_context가 epoll_wait 을 하면 blocking 될 텐데, 그러면 fd event가 올 때 까지 무작정 기다리는가:

- io_context는 job queue에 job이 없는 경우에만 epoll_wait 을 한다

 

다음 글:

"C++ 면접 질문) 람다 함수 형식을 설명해주세요."