увеличить Asio, принимая 100% процессора на чтение - PullRequest
0 голосов
/ 24 августа 2009

Я сделал приложение для сокетов, которое использует Boost Asio, хотя, как мне кажется, это занимает много процессора, когда я пытаюсь прочитать что-нибудь из сокета.

Atm. Я использую класс-оболочку, поэтому мне не нужно открывать заголовочные файлы boost в моем заголовочном файле, который выглядит примерно так:

class SocketHandle
{
public:
    SocketHandle()
    {
        m_pSocket = NULL;
        m_pService = NULL;
    }

    ~SocketHandle()
    {
        delete m_pSocket;
        delete m_pService;
    }

    void connect(const char* host, const char* port)
    {
        if (m_pSocket || m_pService)
            return;

        m_pService = new boost::asio::io_service();

        tcp::resolver resolver(*m_pService);
        tcp::resolver::query query(tcp::v4(), host, port);
        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
        tcp::resolver::iterator end;

        m_pSocket = new tcp::socket(*m_pService);

        boost::system::error_code error = boost::asio::error::host_not_found;

        while (error && endpoint_iterator != end)
        {
            (*m_pSocket).close();
            (*m_pSocket).connect(*endpoint_iterator++, error);
        }

        if (error)
            throw ...
    }

    tcp::socket* operator->()
    {
        return m_pSocket;
    }

private:
     tcp::socket *m_pSocket;
     boost::asio::io_service *m_pService;
};

и затем я читаю из сокета так:

size_t recv(char *data, size_t size)
{
    boost::system::error_code error;
    size_t len = (*m_pSocket)->read_some(boost::asio::buffer(data, size), error);

    if (error)
               throw ...

    return len;
}

Я что-то не так делаю? Есть ли лучший способ чтения данных из сокета?

Повышение 1.39.0 Visual C ++ окна

Ответы [ 3 ]

1 голос
/ 09 ноября 2009

Изменение, которое вы можете рассмотреть (и я настоятельно рекомендую), состоит в том, чтобы сделать ваши вызовы сокетов асинхронными. Таким образом, вам не нужно беспокоиться о блокировке потоков или любых внутренних вызовах сокетов (я подозреваю, что это может быть то, что вы видите). Вместо этого вы просто предоставляете обратный вызов, который будет получать любые ошибки и количество полученных байтов.

Существует множество примеров в документации Boost, иллюстрирующих, как это сделать, и я обнаружил, что это позволяет гораздо более эффективно использовать потоки и ресурсы процессора.

0 голосов
/ 11 сентября 2009

Попробуйте вместо этого использовать функцию free,

size_t len = asio::read(*m_pSocket,asio::buffer(data, size), error);
0 голосов
/ 24 августа 2009

Вам следует избегать напряженного цикла while:

// BAD.
while (error && endpoint_iterator != end)
{
    (*m_pSocket).close();
    (*m_pSocket).connect(*endpoint_iterator++, error);
}

Вместо этого попробуйте что-то вроде:

try
{
    (*m_pSocket).connect(*endpoint_iterator++, error);
    // ...
}
catch (std::exception& ex)
{
    // Release resources, then try connecting again.
}

Также посмотрите эти примеры at для правильных идиом использования Asio.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...