Я реализую свой собственный атомный класс как на конкретном проекте , в котором у меня нет доступа к атомной библиотеке C++ 11. У меня есть следующий код до сих пор:Регистр возвращаемого значения и порядок вызова деструктора
class CAtomicLong
{
public:
CAtomicLong(long lVal) : m_lValue(lVal) {}
long operator+(long lVal)
{
CAutoLock lock(m_lock);
m_lValue += lVal;
return m_lValue;
}
private:
CMyMutex m_lock;
long m_lValue;
};
Предположит, что CMyMutex
обычай обертка мьютекса, и CAutoLock
класс, чей деструктор разблокирует объект, переданный ему во время его строительства. В любом случае эти детали в значительной степени не имеют отношения к этому вопросу.
Что я хотел бы знать, так это безопасно возвращать m_lValue
; то есть будет ли он скопирован в регистр для возврата до называется деструктор для lock
? Я спрашиваю, как меня беспокоят разорванные чтения и записи, потому что если деструктор называется до, регистр возврата устанавливается другим потоком, который может начать изменять m_lValue
при его копировании для возврата.
Я рассмотрел разборку в Visual Studio для такого кода, и он показывает, что обратный вызов выполняется до деструктор вызывается, но: а) я действительно не знаю, что я глядя на сборку (я все еще учусь :)) и б) Я не знаю, является ли это стандартным поведением (опять же, я все еще участвую). Самый безопасный обходной путь для этого потенциала проблем
long operator+(long lVal)
{
CAutoLock lock(m_lock);
long lTemp = (m_lValue += lVal);
return lTemp;
}
... но если это перебор, я предпочел бы знать сейчас.
На какой платформе вы работаете? Большинство из них имеют встроенный прирост и выборку атома, который вы можете использовать вместо mutex. – Dani
Это должно работать на Windows, Solaris Sparc и Linux. Я знаю, что в Windows есть атомарные функции инкремента, но не удается найти функцию атомного извлечения, и у меня нет доступа к требуемым функциям в Solaris. Отсюда этот вопрос. – Wad
В C++ нет «регистров». Код правильный, как написано. –