Должен ли я вызывать socket :: connect () из обработчика, вызываемого resolver :: async_resolve ()? - PullRequest
1 голос
/ 02 октября 2011

Я использую класс-оболочку для представления сетевого подключения.Моя реализация содержит метод с именем async_connect(), который разрешает хост / службу и подключается к связанной конечной точке (если это возможно).Примерно так:

void tcp::connection::async_connect(std::string const& host, std::string const& service,
    protocol_type tcp = protocol_type::v4())
{
    std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::async_connect()" << std::endl;

    resolver(m_io_service).async_resolve(resolver::query(tcp, host, service),
        boost::bind(&connection::resolve_handler, this, _1, _2));
}

То, что я хочу знать, это установление соединения с обработчиком, вызванным завершением метода async_resolve.

Я не уверениспользуется ли основной поток или рабочий поток для вызова обработчика.Таким образом, я должен вызвать socket::connect() (это было бы наиболее разумным способом, если этот код был бы выполнен из рабочего потока) или снова запустить асинхронную операцию (socket::async_connect() - которая должна использоваться при выполнении основным потоком).

void tcp::connection::resolve_handler(boost::system::error_code const& resolve_error,
    tcp::resolver::iterator endpoint_iterator)
{
    std::cout << "thread [" << boost::this_thread::get_id() << "] tcp::connection::resolve_handler()" << std::endl;

    if (!resolve_error)
    {
        boost::system::error_code ec;
        m_socket.connect(*endpoint_iterator, ec);
    }
}

Из вывода консоли я заметил, что мой resolve_handler вызывается из рабочего потока.Итак, можно ли позвонить сюда socket::connect()? 1015 *

1 Ответ

2 голосов
/ 02 октября 2011

IMO При использовании asio хорошо придерживаться модели программирования single .

Вы можете использовать синхронные (блокирующие) вызовы asio, когда вы вызываете несколько методов (разрешение, подключение и т. Д.), И каждый из них блокируется до тех пор, пока не станет доступен результат или ошибка.Однако, если вы используете модель асинхронного программирования, ваш основной или вызывающий поток обычно блокируется на io_service :: run, и указанные обработчики вызываются из другого потока (как в случае, который вы описали).При использовании этой модели программирования вы обычно вызываете следующий метод async из обработчика (рабочего потока), поэтому вместо вызова socket :: connect вы будете вызывать socket :: async_connect.Мне кажется, что вы пытаетесь смешать две разные модели.Я не уверен, что означает смешивание двух моделей (когда ваш вызывающий поток заблокирован на io_service :: run) и вы вызываете синхронный метод из обработчика.

...