C ++ Atomic fetch_add - PullRequest
       21

C ++ Atomic fetch_add

0 голосов
/ 04 декабря 2018

Это не сетевой вопрос.Это вопрос об атомарности, но сценарий окружает контекст сети.

У меня есть несколько потоков, получающих фрагменты сетевого сообщения.Каждый из них должен увеличивать атомарную переменную TotalBytesReceive, пока не будет достигнуто значение TotalBytes.У меня странное поведение с атомистикой, что, вероятно, связано с моим неправильным пониманием чего-либо.

В нескольких потоках:

size_t BytesReceived = // number of bytes received in this thread
bool IsMessageFinished = msg->IsMsgFinished(BytesReceived);
if(IsMessageFinished) 
     {do something else}

Объект msg, который является общим, содержит

class Msg
{
    std::vector<char> MessageData;          // The data received for the message
    const size_t TotalBytes;                      // The final size of the complete message
    std::atomic<size_t> TotalBytesReceived; // The bytes received so far
    std::mutex m_mutex;                     // Just for testing

public:
    Msg(size_t totalbytes) : TotalBytesReceived(0), TotalBytes(totalbytes) 
    {
        MessageData.resize(TotalBytes);
    }

    bool IsMsgFinished(size_t BytesReceived)
    {
        // std::unique_lock<std::mutex> lock(m_mutex); // uncommenting fixed the problem
        size_t newtotal = TotalBytesReceived += BytesReceived;

        std::stringstream ss;
        ss << BytesReceived << " received. New total " << newtotal << '\n';
        std::cout << ss.str(); // For diagnostics

        return newtotal == TotalBytes;
    }

    // Other functions for setting MessageData aren't important here
}

Большая проблема заключается в том, что когда несколько потоков вызывают IsMsgFinished, мой диагностический вывод показывает, что newtotal имеет одно и то же значение несколько раз.Это не должно быть возможно.(BytesReceived никогда не равен 0) Есть ли здесь грубая ошибка?

Если я использую мьютекс и unique_lock в функции IsMsgFinished, все работает отлично, но я бы не хотел использовать блокировку.

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