atomic
не имеет прямого отношения к безопасности потока. Это просто гарантирует, что операции над ним в точности соответствуют атомарным. Даже если бы все ваши операции были атомарными, ваш код не обязательно был бы потокобезопасным.
В вашем случае код должен быть безопасным. Только 1 поток за один раз может ввести printCurrent()
. Во время выполнения этой функции другие потоки могут вызывать addLog()
(но одновременно только 1). В зависимости от того, был ли switchCurrent
уже выполнен, эти записи войдут в текущий журнал или нет, но ни одна не будет введена во время итерации по нему. Только 1 поток одновременно может ввести addLog
, который разделяет свой мьютекс с switchCurrent
, поэтому они не могут быть выполнены одновременно.
Это будет иметь место, даже если вы сделаете idxActive
простым int Mh, модель памяти C ++ работает только с однопоточным кодом - поэтому я не слишком уверен, теоретически может ли он сломаться Это. Я думаю, что если вы сделаете idxActive
энергозависимым (по сути, вообще не позволяющим оптимизировать загрузку / хранение в нем), это будет нормально для всех практических целей. В качестве альтернативы вы можете удалить мьютекс из switchCurrent
, но тогда вам нужно оставить idxActive
атомарным.
В качестве улучшения я бы позволил switchCurrent
вернуть старый индекс вместо его пересчета.