boost: asio async_receive_from ведет себя синхронно - PullRequest
0 голосов
/ 29 июня 2011

В приведенном ниже коде asynch_receive_from ведет себя синхронно. Это не возвращается, пока данные не получены. Посмотрите на журнал в конце указывает на это. Это может быть не так сначала это очевидно, потому что поступает довольно высокая скорость поступления данных. Но когда нет данных, а всего лишь одна секунда сообщения пульса, возврат из этих асинхронных вызовов также составляет порядка одной секунды.

Вопрос в том, почему эти асинхронные вызовы не возвращаются немедленно (в течение нескольких микросхем) и не читаются байты?

Я подумал, что, возможно, наличие других элементов в очереди выполнения облегчит процесс, думая, что если в очереди нет ничего для запуска, io_services превратит функцию асинхронизации в функцию синхронизации, так как ей больше ничего не нужно делать. Но я добавил 2 сообщения перед асинхронным вызовом, который, как я полагаю, поместил бы что-то в очередь выполнения перед асинхронным вызовом. Но, похоже, это не имело значения.

Любая помощь будет оценена. Я новичок в библиотеке boost :: asio.

void receiver::handle_receive_from(const boost::system::error_code& error,
      size_t bytes_recvd)
{
    static char logBuf[128];    
    string dStr;
    int rVal;
    unsigned int seqNo;

    sprintf_s(logBuf, sizeof(logBuf), "BytesRead:%d", bytes_recvd);
    MyLog(logBuf);
    MyLog("1"); 
    MyLog("2");
    iosP->post(boost::bind(&receiver::postTestHandler, this));
    iosP->post(boost::bind(&receiver::postTestHandler, this));
    socket_.async_receive_from(
                boost::asio::buffer(data_, max_length), sender_endpoint_,
                boost::bind(&receiver::handle_receive_fromTwo, this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));     

    MyLog("3");

}

void receiver::handle_receive_fromTwo(const boost::system::error_code& error, size_t bytes_recvd)
{
    char logBuf[128];

    sprintf_s(logBuf, sizeof(logBuf), "Two BytesRead:%d", bytes_recvd);
    MyLog(logBuf);

    MyLog("1-Two"); 
    MyLog("2-Two");
    iosP->post(boost::bind(&receiver::postTestHandler, this));
    iosP->post(boost::bind(&receiver::postTestHandler, this));
    socket_.async_receive_from(
                boost::asio::buffer(data_, max_length), sender_endpoint_,
                boost::bind(&receiver::handle_receive_from, this,
                boost::asio::placeholders::error,
                boost::asio::placeholders::bytes_transferred));         


    MyLog("3-Two");

}

void receiver::postTestHandler()
{   
    int count(0);
    MyLog("***postTestHandler entry***");
    printf("***postTestHandler entry***\n");
    printf("Exiting postTestHandler\n");
    MyLog("Exiting postTestHandler");
}

Фрагмент журнала

[11:57:51.653647]BytesRead:16
[11:57:51.653660]1
[11:57:51.653662]2
[11:57:51.653692]3
[11:57:51.653697]***postTestHandler entry***
[11:57:51.654310]Exiting postTestHandler
[11:57:51.654315]***postTestHandler entry***
[11:57:51.654657]Exiting postTestHandler
[11:57:51.727494]Two BytesRead:67
[11:57:51.727503]1-Two
[11:57:51.727506]2-Two
[11:57:51.727524]3-Two
[11:57:51.727529]***postTestHandler entry***
[11:57:51.728060]Exiting postTestHandler
[11:57:51.728065]***postTestHandler entry***
[11:57:51.728407]Exiting postTestHandler
[11:57:52.438916]BytesRead:67
[11:57:52.438929]1
[11:57:52.438932]2
[11:57:52.438961]3
[11:57:52.438965]***postTestHandler entry***
[11:57:52.439568]Exiting postTestHandler
[11:57:52.439573]***postTestHandler entry***
[11:57:52.439914]Exiting postTestHandler
[11:57:52.581333]Two BytesRead:67
[11:57:52.581346]1-Two
[11:57:52.581349]2-Two
[11:57:52.581375]3-Two
[11:57:52.581381]***postTestHandler entry***
[11:57:52.582011]Exiting postTestHandler
[11:57:52.582016]***postTestHandler entry***
[11:57:52.582358]Exiting postTestHandler
[11:57:52.582364]BytesRead:67
[11:57:52.582367]1
[11:57:52.582370]2
[11:57:52.582377]3
[11:57:52.582381]***postTestHandler entry***
[11:57:52.582717]Exiting postTestHandler
[11:57:52.582722]***postTestHandler entry***
[11:57:52.583055]Exiting postTestHandler
[11:57:52.583061]Two BytesRead:67
[11:57:52.583064]1-Two
[11:57:52.583066]2-Two
[11:57:52.583077]3-Two
[11:57:52.583081]***postTestHandler entry***
[11:57:52.583418]Exiting postTestHandler
[11:57:52.583423]***postTestHandler entry***
[11:57:52.583755]Exiting postTestHandler
[11:57:52.616525]BytesRead:67
[11:57:52.616531]1
[11:57:52.616533]2
[11:57:52.616549]3
[11:57:52.616553]***postTestHandler entry***
[11:57:52.617015]Exiting postTestHandler
[11:57:52.617020]***postTestHandler entry***
[11:57:52.617362]Exiting postTestHandler

1 Ответ

2 голосов
/ 20 февраля 2012

Не уверен, если у вас все еще есть эта проблема, но он заблокируется после того, как вы вызовете io_service.run (), потому что он будет бесконечно искать пакеты, которые он получил.Если вы хотите, чтобы он проверял обратные вызовы, но не блокировал их, если их нет, используйте io_service.poll ().Если вы хотите, чтобы он выполнял ровно один обратный вызов (если есть один или несколько запросов), используйте io_service.poll_one ().

Не уверен, что это ваша проблема, или если проблема сохраняетсяЯ знаю, что этот вопрос очень старый), но удачи!

edit (в ответ на ваш комментарий):

Если вы используете io_service.run (), тогдаэтот поток всегда будет посвящен обработке обратных вызовов asio.Однако, если вы используете io_service.poll (), вы можете обрабатывать обратные вызовы, когда захотите, а затем делать что-то еще в это время.io_service.poll () ни в коем случае не быстрее, чем io_service.run (), он просто дает вам возможность обрабатывать обратные вызовы в любое время, а не всегда неопределенно.

Вы, вероятно, можете представить себе io_service.run () быть реализованным так:

void IOService::run()
{
    while (true)
    {
        poll();
    }
}

Обратите внимание, что это не реализовано так.Но это может прояснить представление о том, что делают прогоны и опросы.

...