프로그래밍/c++ - boost::asio

코루틴(coroutine) 사용 중 주의해야 할 부분?

제페 2015. 12. 26. 03:39
반응형


얼마 전부터, 코루틴을 사용한 비동기 프로그래밍에 관심이 있었다.

그래서 asio example로 나와있는 코드(spawn 예제)를 보면서 다음과 같은 코드를 짜봤는데, 

이런 상황에 대한 문제가 있을 거 같더라. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    void listen(boost::asio::ip::tcp::endpoint endpoint, bool reuse_address = true)
    {
      boost::asio::spawn(strand_, 
        [this, endpoint, reuse_address](boost::asio::yield_context yield)
        {
          tcp::acceptor acceptor{ service_, endpoint, reuse_address };
          acceptor.listen();
 
          do
          {
            boost::system::error_code error;
            acceptor.async_accept(socket_, yield[error]);
 
            if (!error)
            {
              this->accepted({ std::move(socket_) });
              acceptor.close();
            }
 
          } while (true);
        }
      );
    }

cs


클라이언트로 부터 연결 요청을 듣는 listen 함수를 작성했다. asio example들을 참고하면서. 

근데 6번 라인을 보자. acceptor가 마치 지역 변수처럼 선언이 되어있다. 

근데 난 저 acceptor를 중지하고 싶은데? 

음.. 이런 상황을 가정하니 좀 난감해졌다. 저 acceptor에 어떻게 접근을 할 것인가. -__..


0. 코루틴과 연결되어있는 명령 큐(이건 배보다 배꼽이 더 커지는 듯 -_-..)

1. acceptor를 멤버로 가지고, spawn 핸들러에서 acceptor를 비활성화(close) 시킨다.(이게 가장 나을 듯!)


그러면 spawn 안에 있는 async_accept의 결과로 error가 반환이 될 것이고, 자연스레 루프를 벗어나도록 만들 수 있을 것이다.

굉장히 아무것도 아닌 문제이다.

하지만 코루틴을 쓰는 곳이 많아지다보면 저런 문제로 버그를 만드는 일이 분명 있을 거 같다는 느낌이 든다.

코루틴을 정말 조금만 썼는데도 느끼는데, 디버깅이 굉장히 힘들 듯 하다. accept와 연결된 소켓을 대상으로 receive만 하는데도 그렇다.

거기에 추가적인 로직까지 껴든다면? 굉장히 난잡해질 것이다.

tcp socket의 receive 부분과, acceptor의 accept 부분만 코루틴으로 했는데도 코드가 여기저기로 뛰더라 ㅡㅡ; 


사용에 있어서 주의해야겠다. 어렴풋이라도 기억해놓자. 코루틴 취소에 대한 염두.

반응형