특정 프로젝트에서 내 자신의 원자 클래스를 구현하고 있습니다. 에서 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에서 이와 같은 코드로 디스 어셈블리를 한 번 보았습니다. 전에이 호출되기 전에 반품 전화가 표시되는 것으로 보입니다. 그러나 a) 나는 실제로 무엇인지 모르겠습니다. 어셈블리로보고 (아직도 배우고 있어요 :)) 그리고 b) 이것이 표준 행동인지 다시 모르겠다. (나는 여전히 배우고있다.) 이 잠재적 문제의 안전한 해결 방법은
long operator+(long lVal)
{
CAutoLock lock(m_lock);
long lTemp = (m_lValue += lVal);
return lTemp;
}
입니다 ...하지만이 과잉이면 차라리 지금 알고있는 것입니다.
어떤 플랫폼을 사용하고 있습니까? 그들 대부분은 원자 증가를위한 내장 함수를 가지고 있으며, 뮤텍스 대신 사용할 수 있습니다. – Dani
이것은 Windows, Solaris Sparc 및 Linux에서 작동해야합니다. Windows에서 원자 증가 함수가 있지만 atomic 검색 함수를 찾을 수 없으며 Solaris에서 필요한 함수에 액세스 할 수 없습니다. 그러므로이 질문. – Wad
C++에는 "레지스터"가 없습니다. 코드는 작성된대로 정확합니다. –