2011-09-03 6 views
5

그래서 boost :: asio 라이브러리를 사용하여 비동기 읽기 및 쓰기를 수행하는 소켓 클래스를 만들었습니다. 작동하지만 몇 가지 질문이 있습니다.boost :: asio 비동기 작업 및 리소스

는 여기에 기본 코드 예제 :

class Socket 
{ 
public: 
    void doRead() 
    { 
     m_sock->async_receive_from(boost::asio::buffer(m_recvBuffer), m_from, boost::bind(&Socket::handleRecv, this, boost::asio::placeholders::error(), boost::asio::placeholders::bytes_transferred())); 
    } 

    void handleRecv(boost::system::error_code e, int bytes) 
    { 
     if (e.value() || !bytes) 
     { 
      handle_error(); 
      return; 
     } 
     //do something with data read 
     do_something(m_recvBuffer); 

     doRead(); //read another packet 
    } 

protected: 
    boost::array<char, 1024> m_recvBuffer; 
    boost::asio::ip::udp::endpoint m_from; 
}; 

프로그램이 다음 다른를 읽을 준비, 패킷을 읽어을 처리 할 것으로 보인다. 단순한. 하지만 스레드 풀을 설정하면 어떻게됩니까? 읽은 데이터를 처리하기 전이나 후에 doRead()에 대한 다음 호출이 있어야합니까? do_something() 앞에 놓이면 프로그램은 즉시 다른 패킷을 읽을 수 있으며 나중에 넣으면 스레드가 묶여서 do_something()이 무엇이든 할 수 있으며 이는 다소 시간이 걸릴 수 있습니다. 처리하기 전에 doRead()을 넣으면 처리하는 동안 m_readBuffer의 데이터가 변경 될 수 있습니다.

또한 async_send_to()을 사용하는 경우 데이터가 범위를 벗어날 때까지 실제 송신이 이루어지지 않을 수도 있기 때문에 임시 버퍼로 보낼 데이터를 복사해야합니까? 즉

void send() 
{ 
    char data[] = {1, 2, 3, 4, 5}; 
    m_sock->async_send_to(boost::buffer(&data[0], 5), someEndpoint, someHandler); 
} //"data" gets deallocated, but the write might not have happened yet! 

또한 소켓이 닫히면 handleRecv가 중단되었음을 나타내는 오류와 함께 호출됩니다. 호출되는 mySockethandleRecv() 전에 삭제됩니다 기회가 있기 때문에 나는이 오류가 발생할 수

Socket* mySocket = new Socket()... 
... 
mySocket->close(); 
delete mySocket; 

을 할 경우/완료?

+0

+1 좋은 질문이지만, 미래에는 Stackoverflow에 대한 별도의 질문으로 나누는 것이 좋습니다. –

답변

2

많은 질문을 여기에서 한 번에 하나씩 시도해 보겠습니다.

하지만 스레드 풀을 설정하면 어떻게됩니까?

Boost.Asio와 스레드 풀을 사용하는 전통적인 방법은 io_service::run()from multiple threads를 호출하는 것입니다. 그러나 이것은 하나의 크기에 맞는 답변이 아니며 확장 성과 성능 문제가있을 수 있지만이 방법론은 구현하기가 훨씬 쉽습니다. 더 많은 정보가있는 Stackoverflow에는 많은 유사한 questions이 있습니다.

데이터를 처리하기 전후에 doRead를 호출해야합니까? do_something() 전에 넣으면 프로그램 이 즉시 다른 패킷을 읽기 시작할 수 있으며, 나중에 넣으면 스레드는 do_something이하는 모든 작업을 수행합니다. 일 수 있습니다.

이것은 실제로 do_something()m_recvBuffer과 관련이 있는지에 따라 다릅니다. do_something()doRead()과 병행하여 io_service::post()을 사용하여 호출하려면 m_recvBuffer 사본을 만들어야 할 수 있습니다.

내가 처리하기 전에 doRead()를 넣으면 내가 그것을 처리하고있어하면서, m_readBuffer의 데이터를 의미 가 변경 될 수 있습니까?

이전에 언급했듯이 이것은 가능할 수 있습니다.실제 전송 데이터가 범위를 벗어나 떨어졌다 때까지 을 발생하지 않을 수도 있기 때문에

, 내가 async_send_to() 사용하고 있다면, 나는 임시 버퍼에 를 송신하는 데이터를 복사해야합니까? documentation describes로서

는 호출자까지 (는) 버퍼가 비동기 동작의 시간 동안 범위 내에 유지되도록하는 것이다. 의심 스럽지만 현재 예제에서는 data[]이 범위를 벗어날 것이므로 정의되지 않은 동작을 호출합니다. 소켓이 닫힐 때

또한,의 handleRecv() 오류가이 중단 된 지시와 를 호출합니다. 당신은 소켓을 계속 사용하려면

, cancel()interrupt outstanding에 비동기 작업을 사용합니다. 그렇지 않으면 close()이 작동합니다. 어느 시나리오에서든 비동기 작업으로 전달되는 오류는 boost::asio::error::operation_aborted입니다.

관련 문제