작성
·
480
1
Arrow->SetTarget을 통해 Monster의 RefCount를 증가시켜주려고 할때, 다른 쓰레드에 의해서 Monster에 대해 ReleaseRef를 호출하게 되면,
RefCount를 증가하기 전이기 때문에 ReleaseRef 안에서 Monster가 삭제되는 문제가 있는 것으로 이해했습니다.
헷갈리는 부분은 다음과 같습니다.
SharedPtr를 통한 SetTarget을 할 경우 Target의 RefCount가 최소한 1이상 일 것이다라는 부분입니다.
여기서 SetTarget을 하면 복사생성자가 호출되고,
복사생성자에서 AddRef를 통해 RefCount를 증가시켜주려고 할때 다른 쓰레드가 Monster를 ReleaseRef하면,
거기서도 위와 같이 Target을 삭제하는 문제가 생길것 같은데
두 방식의 다른점이 무엇인지 아리송 해서 질문 올립니다.
답변 4
1
1)
이 부분에서 new CMonster()가 아니라,
실제 상황이라면 ObjectManager->GetMonster()와 같은 형태로 몬스터를 갖고 올겁니다.
2)
이 때 수동 refcounting을 한다면,
GetMonster()를 반환받은 다음, 거기에다가 우리가 ->AddRef()를 호출해서 +1을 해줘야 하는데
그 순간 하필 다른 쓰레드에서 ObjectManager->Destroy(id)를 호출해
해당 몬스터가 메모리에서 날라갔다면 낭패가 되겠죠.
3)
SharedPtr를 사용할 것이라면, 모두가 통일된 정책을 이용해야 합니다.
다른 쓰레드도 마찬가지로 SharedPtr을 사용한다 가정하고 다시 생각해보면,
ObjectManager->GetMonster()는 SharedPtr<Monster>를 반환할 것이고,
이미 return할 때 정책상 SharedPtr 복사는 AddRef()를 호출해준 상태에서 반환이 되겠죠.
4)
이 상태에서 다른 쓰레드가 ObjectManager->Destroy(id)를 호출해도,
refcount가 0이 되지 않기 때문에 당장 delete하지 않고 놔두게 될겁니다.
0
Destroy(id)가 호출되어 RefCount==0 조건이 만족하는 것을 확인했고, delete ptr을 수행 하려고하는 순간
다른 쓰레드의 개입으로 refCount가 증가되버리는 경우는 없는건가요?
0
ObjectManager를 통해서든 다른 루트를 통해서든
Monster 를 참조하고 접근하려면 무조건 RefCount를 증가시켜야 한다
(SharedPtr 복사에 의해)
~가 핵심이고 따라서 누군가가 Monster의 SharedPtr를 통해
몬스터를 참조하고 있는 상태라면, 해당 메모리는 절대 안 날라간다 보장할 수 있는 것입니다.
0
1)
Monster는 ObjectManager에서 관리하고,
다른 쓰레드에서도 통일된 정책을 사용해 GetMonster()를 하면 AddRef()를 호출해준 상태로
반환이 되는것은 잘 이해가 되엇습니다.
다시 말하자면,
GetMonster()할때 반환해주는 몬스터에 대해 내부적으로 RefCount를 증가시키고 반환해주기 전까지는,
다른 쓰레드에서 해당 몬스터에 대해 접근 할 방법이 없다 (ObjectManager안에 있으므로)
는것으로 이해하면 될까요?
모든걸 SharedPtr로 관리한다면,
애당초 그런 상황이 발생할 수가 없습니다.
1에서 0으로 내려갔다는건 현재 쓰레드 말고는
아무도 해당 포인터를 기억하지 않는다는 의미이기 때문이죠