У меня есть вопрос относительно изменчивого ключевого слова, на который я не могу найти ответ.
В моем приложении у меня есть класс данных, который совместно используется как буфер состояния между потоками, и мне нужно, чтобы он регулярно обновлялся из нескольких потоков.
Класс выглядит так:
class CBuffer
{
//Constructor, destructor, Critical section initialization/destruction
//...
volatile wstring m_strParam;
//...
void InterlockedParamSetter(const wstring &strIn);
wstring InterlockedParamGetter();
ParamSetter(const wstring &strIn);
wstring ParamGetter();
Lock();
Unlock();
}
void CBuffer::InterlockedParamSetter(const wstring &strIn)
{
Lock();
const_cast<wstring>(m_strParam) = strIn;
Unlock();
}
//... other f-ns
Но компилятор жалуется на преобразование const_cast.
Похоже, я злоупотребляю ключевым словом volatile, но в то же время я не могу позволить кэшировать параметры между вызовами, потому что, если их назначат два или три потока, что-то может пойти не так.
Как вы пишете потоки / кеширующие классы на C ++?
P.S .: Пока блокировка не является узким местом, и блокировки в значительной степени являются однострочными, поэтому на данный момент сериализация и блокировка не являются проблемой с точки зрения производительности. Конечно, если есть лучший алгоритм, я с удовольствием выслушаю.
EDIT:
Мне все еще неясно ...
Рассмотрим этот пример (вставка + ссылка времени кода);
void Thread1Func()
{
//Unrolled, inlined InterlockedParamSetter()
EnterCriticalSection(&cs);
WriteTo(CBuffer::m_strParam);//write to buffer, wstring not volatile, cache it
LeavCriticalSection(&cs);
//Unroll end
//DoSomethingElse
//!!!!Thread 2 does InterlockedParamSetter
//which causes wstring::reserve and invalidates old pointers!!!!
//Unrolled, inlined InterlockedParamSetter()
EnterCriticalSection(&cs);
WriteTo(CBuffer::m_strParam);//oh, good, we have a pointer to old buffer
//cached in one of the registers, write to it -> access violation
LeavCriticalSection(&cs);
//Unroll end
}