방해받는 공유 포인터를 쓰고 있으며 참조 카운터에 C++ 11 <atomic>
기능을 사용하고 있습니다. 여기에 내 코드 관련 조각은 다음과 같습니다C++ 11 원자력 및 간섭 공유 포인터 참조 횟수
//...
mutable std::atomic<unsigned> count;
//...
void
SharedObject::addReference() const
{
std::atomic_fetch_add_explicit (&count, 1u,
std::memory_order_consume);
}
void
SharedObject::removeReference() const
{
bool destroy;
destroy = std::atomic_fetch_sub_explicit (&count, 1u,
std::memory_order_consume) == 1;
if (destroy)
delete this;
}
내가 memory_order_acquire
과 memory_order_release
첫째로 시작했지만 그때 memory_order_consume
이 충분해야한다고 자신을 설득했다. 더 심의를 마친 후에도 memory_order_relaxed
조차도 작동 할 것입니다.
이제는 조작에 memory_order_consume
을 사용할 수 있는지 또는 더 약한 주문 (memory_order_relaxed
)을 사용할 수 있습니까? 아니면 더 엄격한 주문을 사용해야합니까?
카운터는 기본적으로'delete' 문에 대한 재귀 적 잠금 역할을하기 때문에'removeReference'의'addReference'와'releaseRelease'의 "acquire"는 올바른 순서입니다. 그러나 당신의'addReference'는 카운터가 0이 아닌지 확인해야합니다! –
@KerrekSB : 객체가'SharedPtr <> '에 할당되기 전에 객체가 처음 생성 된 후에 카운터는'addReference()'에서 0이 될 수 있습니다. Acquire/release 의미론은 항상 작동해야합니다. 하지만 더 약한 주문 제약 조건을 사용할 수 없으며 그 이유는 무엇입니까? – wilx
0에 대하여 : refcount가 1이라고 가정하십시오. 이제 스레드 1이 객체를 삭제하려고하고 빼기를 호출합니다. 이 시점에서 스레드 2가 스레드 수를 늘리려고하면 0을 1 씩 증가 시키지만 스레드 1은 계속 진행하여 어쨌든 개체를 삭제합니다. 그것은 피해야합니다. –