A. 스마트 포인터
1. 멀티스레드와 스마트 포인터
a. 객체 포함 레퍼런스 카운트 블록
💥 일반 포인터를 사용하면 안되는 이유
주소값을 진짜 사용해도 되는지 안되는지에 대한 정보가 없어서
포인터를 그냥 들고있으면 생명 주기가 꼬여서 날라가고... 난리남
그래서 레퍼런스 카운트를 사용해 주소값을 관리하게 됨
객체에 포함, 레퍼런스 카운트를 관리하는 블록 2가지로 만들 수 있음
1) 객체에 포함하는 refCount
위 순간 주소값을 기억하는 애가 하나 증가함
위와같이 카운팅을 쳐서 관리하는 방법이 있음 (수동 레퍼런스 카운트)
위를 멀티스레드 환경에서 작업할 시 알아야 할것
=> 증감연산자 -> 아토믹으로 해결
여기서 아토믹만 붙인다고 끝? -> 스마트 포인터를 사용해야 함
위는 멀티스레드 환경에서만 위험!!
b. 수동 관리의 위험성
Knight가 AddRef()일때 위 코드가 먼저 실행되지 않고
ReleaseRef()한다면 0-> -1이 되면서 없어지게 되어 오류
그래서 생명보장이 받지 않은 상태에서
*****가 끼어들어서 뭐가 실행되게 되면 안전하지 않음!
위와같이 수동으로 관리해야하는건 정말 비효율적이다
위를 이해하고 난 후 스마트 포인터 공부!
2. 스마트포인터
a. 스마트포인터와 레퍼런스 카운팅 블록
이제 위와같이 객체안에 넣지 않고 따로 관리
2) 레퍼런스 카운팅 블록 (표준 tsharedptr 방법)
TSharePtr 클래스를 만들어서 관리하자
이렇게 만들어준다음
기본생성자에서 바로 1을 증가시키도록 만들어줌 (수동아님)
=> 궁극적인 목표 RefCount 클래스를 통해 주소를 자동으로 카운팅해주는 것
복사를 해도 원래 데이터 값을 그대로 유지함
그 뒤로 참조파일을 끌어와서 위 클래스를 완성시킴
++ 아래는 참조파일 추가한 코드
복사, 이동시 자기 자신을 폭파시킴
b. 스마트 포인터 규칙
이제 생포인터가 눈에 띄면 안됨
이렇게 KnightRef를 만들어주고 (모든걸 관리)
한번은 만들어주고 (new Knight())
이제 이건 절대 스마트포인터로만 사용된다
Test함수를 실행하면 복사가 되면서 카운팅 +1 이된다
만약 중간에 끼어들어가서 (멀티스레드) 나이트를 소멸시키면 어떻게 될까?
=> 어떤 식으로 하건 knight가 존재하면 괜찮다
따라서 1을 한번 소멸시켜줘야 함 (knight->ReleaseRef)
이건 따로 만들어준 방법을 사용하기에 하는것임
카운팅 1 증가시키는 것 자체가 복사비용이 부담스러울 수 있음 (아토믹 사용)
잠시만 사용하고 싶을 땐 어떻게 할까? 👉 & 사용
참조값으로 받아서 사용하면 복사비용이 없다
-> 이것도 스마트포인터를 들고있어서 중간에 삭제시킬수가 없음
c. 스마트포인터의 소멸과 사이클
최종적으로 소멸은 어디서 이루어지냐?
-> 알 수 없음.. 누군가가 막타를 친다 >< (그래도 생포인터보단 ㄱㅊ)
순환 문제(사이클)
스마트 포인터의 순환(사이클) 문제가 발생하면 어떤 문제가 일어날까?
-> 리크 포인터를 사용
객체의 생명주기에는 영향을 주지 않고 레프카운트 블록만 유지하는 역할
d. This 와 스마트포인터
스마트 포인터를 사용할 때 발생하는 애매한 상황
위와같이 기사가 이동하는 기능이 있다고 함
다른사람을 대상으로 이동하기는 괜찮은데, 내 자신을 움직이려면 (this)를 사용하기 어려움
This는 애당초 ref카운팅이 들어가지 않는 일반 포인터
일반 포인터를 대상으로 sharedptr을 사용한 꼴
따라서 포인터의 카운트는 1이고, 포인터를 관리하는 애는 this가 되어버림
따라서 포인터 자체가 소멸되어 버리니 문제가 발생됨
이중으로 삭제했기 때문에 오류가 남!
그림으로 설명해보자
나이트와 레퍼런스 카운트 블록은 묶어서 관리가 되고
초록색인 스마트포인터는 두 블록을 묶을 객체를 따로 관리하는 것
근데 this 포인터를 넘겨주면서 새로운 스마트포인터를 생성해
아래 묶음을 삭제시키면서 객체 (노란색)까지 터져버리는 것
따라서 위와같은 이유로 인해 꼭 꼼꼼하게 사용을 해야합니다~!
✨ 해결방법
이와 같이 weakptr 을 사용해 생명 주기에 영향을 주지 않는 포인터를 사용해야 함
Or
Enable_ shared_from_this
'운영체제' 카테고리의 다른 글
[게임 프로그래머 입문 올인원] 멀티쓰레드 프로그래밍 : 이벤트와 조건 변수 (0) | 2024.12.04 |
---|---|
[게임 프로그래머 입문 올인원] 멀티쓰레드 프로그래밍 : 락 기초, 스핀락, 데드락 (0) | 2024.12.03 |
[게임 프로그래머 입문 올인원] 멀티쓰레드 프로그래밍 : 공유자원 (0) | 2024.12.03 |
[게임 프로그래머 입문 올인원] 멀티쓰레드 프로그래밍 : 캐시와 CPU 파이프라인 (1) | 2024.12.03 |
[게임 프로그래머 입문 올인원] 멀티쓰레드 프로그래밍 : 쓰레드 (1) | 2024.12.02 |