mutex em boost :: asio :: write not works

Sep 28 2020

Estou tentando fazer um cliente tcp assíncrono (ele não vai esperar pelo resultado de uma solicitação antes de enviar outra solicitação).

Um método de solicitação se parece com:

std::future<void> AsyncClient::SomeRequestMethod(sometype& parameter)
{
    return std::async(
        std::launch::async,
        [&]()
        {
            // Gonna send a json. ';' at the end of a json separates the requests.
            const std::string requestJson = Serializer::ArraySumRequest(numbers) + ';';
            boost::system::error_code err;

            write(requestJson, err);
            // Other stuff.

O método write chama boost :: asio :: write assim:

void AsyncClient::write(const std::string& strToWrite, boost::system::error_code& err)
{
    // m_writeMutex is a class member I use to synchronize writing.
    std::lock_guard<std::mutex> lock(m_writeMutex);
    boost::asio::write(m_socket,
        boost::asio::buffer(strToWrite), err);
}

Mas parece que ainda vários threads escrevem simultaneamente, pois o que recebo no servidor é:

{"Chave": "Val {" Chave ": Valor}; ue"};

O que devo fazer?

Respostas

3 Jeffrey Sep 28 2020 at 20:05

Você colocou a proteção de bloqueio ao escrever para o asio . Como você pode ver, não há garantia de que a outra extremidade os processará com o mesmo protetor.

Você deve antes colocar o guarda onde você precisa, ao escrever o json , fora do asio:

void AsyncClient::write(const std::string& strToWrite, boost::system::error_code& err)
{
    // m_writeMutex is a class member I use to synchronize writing.
//  std::lock_guard<std::mutex> lock(m_writeMutex);
    boost::asio::write(m_socket,
    boost::asio::buffer(strToWrite), err);
}

return std::async(
    std::launch::async,
    [&]()
    {
        std::lock_guard<std::mutex> lock(m_writeMutex); // <--- here

        // Gonna send a json. ';' at the end of a json separates the requests.
        const std::string requestJson = Serializer::ArraySumRequest(numbers) + ';';
        boost::system::error_code err;

        write(requestJson, err);
        // Other stuff.