문제

댓글 이중 점검 잠금에 대한이 수정에 어떤 문제가 있습니까? 말 :

문제는 객체가 할당되기 전에 생성자가 실행되거나 완료되기 전에 변수를 할당 할 수 있다는 것입니다.

코드를 고려해 봅시다 :

A *a;

void Test()
{
    a = new A;
}

보다 공식적인 분석을 허용하려면 a = new A를 여러 작업으로 나눕니다.

void *mem = malloc(sizeof(A)); // Allocation
new(mem) A; // Constructor
a = reinterpret_cast<A *>(mem); // Assignment

위에서 인용 된 주석은 사실이며, 그것이 어떤 의미에서 어떤 의미입니까? 할당 후 생성자를 실행할 수 있습니까? 가능하다면 MT 안전 때문에 보장 된 주문이 필요할 때 무엇을 할 수 있습니까?

도움이 되었습니까?

해결책

코드가 실행될 때 문제는 그리 많지 않지만 쓰기 주문과 관련이 있습니다.

다음과 같이 가정 해 봅시다.

A()
{
   member = 7;
}

그런 다음 나중에 :

singleton = new A()

이로 인해 할당을 수행하는 코드, 메모리에 쓰기 (멤버), 다른 메모리 위치 (싱글 톤)에 쓰기가 발생합니다. 일부 CPU는 싱글 톤에 쓰기가 끝날 때까지 멤버에 대한 쓰기가 보이지 않도록 쓸 수 있습니다. 본질적으로 시스템에서 다른 CPU에서 실행되는 코드는 싱글 톤이 작성된 곳에 메모리를 볼 수 있지만 회원은 회원이 있습니다. 아니다.

다른 팁

다음은 효과가 있다고 생각합니다.

void Test()
{
    A *temp = new A;
    MemoryWriteBarrier(); // use whatever memory barrier your platform offers
    a = temp;
}

a 정적 저장 시간이있는 글로벌 객체이므로 메인 본문이 실행되기 전에 언젠가 사전에 할당 된 스토리지에서 초기화됩니다. 테스트 호출이 일부 정적 객체 구성 기묘함의 결과가 아니라고 가정하면 a 시간 테스트가 호출되어 전체 구성됩니다.

a = new A;

이 약간 특이한 할당은 포인터를 할당 할 때 표준 사본 할당 작업이 아닙니다. A 객체 나 참조가 아닙니다. 실제로 컴파일하는지 여부와 정확히 부르는 것은 A 포인터를 취하는 과제 연산자가 있습니다 A, 또는 포인터에서 암시 적으로 변환 할 수있는 것 A 또는 여부 A 포인터를 취하는 비외식 생성자가 있습니다 A (또는 기본 클래스에 대한 포인터 A).

편집 후, 코드는 다소 다른 작업을 수행합니다!

개념적으로, 그것은 다음과 같이 더합니다.

A *tmpa;
void *mem = ::operator new( sizeof(A) ); // ( or possibly A::operator new )

try
{
    tmpa = new (mem) A; // placement new = default constructor call
}
catch (...)
{
    ::operator delete( mem );
    throw;
}

a = tmpa; // pointer assignment won't throw.

이와 같이 무언가를 쓰는 위험은 원본에 있지 않은 많은 시퀀스 포인트를 암시 적으로 추가하고 컴파일러가 동작하는 한 이렇게 보이지 않는 코드를 생성 할 수 있다는 것입니다. '마치'실행 프로그램이 결정할 수있는 한 이것에 의해 작성된 것처럼. (현재) 언어가 다른 스레드 작업과의 상호 작용에 대해서는 아무것도 말하지 않은 것처럼 '규칙'규칙이 실행 스레드에만 적용됩니다.

이를 위해 구현에 따라 특정 동작 보증 (있는 경우)을 사용해야합니다.

예, 당신이 준 예제는 내부적으로 일관성이 없지만 (이에 대한 의견에 의해 언급 된 바와 같이), 할당 후 생성자는 호출 할 수 있습니다.

당신은 마음의 평화를 위해 약간의 자물쇠를 던질 수 있지만, 그 잘못을 쉽게 얻는 것도 쉽습니다.

보다

"C ++ 및 이중 체크 잠금의 위험"

Scott Meyers와 Andrei Alexandrescu

http://www.aristeia.com/papers/ddj_jul_aug_2004_revised.pdf

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top