Version: 2022.3
언어: 한국어
커스텀 네이티브 컨테이너 구현
커스텀 NativeContainer 예제

NativeContainer 구조체 복사

네이티브 컨테이너는 값 타입이므로 변수에 할당되면 Unity는 네이티브 컨테이너의 데이터가 저장된 위치에 대한 포인터가 포함된 NativeContainer 구조체를 복사하며, 여기에는 AtomicSafetyHandle 등이 포함됩니다.NativeContainer의 전체 콘텐츠를 복사하지 않습니다.

이 시나리오는 모두 동일한 메모리 영역을 참조하고 모두 동일한 중앙 레코드를 참조하는 AtomicSafetyHandle 오브젝트를 포함하는 NativeContainer 구조체의 사본이 여러 개 있을 수 있음을 의미합니다.

NativeContainer 오브젝트 사본 동작 방식
NativeContainer 오브젝트 사본 동작 방식

위 다이어그램은 모두 동일한 실제 컨테이너를 나타내는 세 가지 다른 NativeArray 구조체의 사본을 보여줍니다.각 사본은 동일한 저장 데이터와 원본 NativeArray와 동일한 안전 데이터를 가리킵니다.그러나 NativeArray의 각 사본에는 해당 사본으로 수행할 수 있는 잡을 나타내는 서로 다른 플래그가 있습니다.안전 데이터에 대한 포인터와 플래그가 결합되어 AtomicSafetyHandle을 구성합니다.

버전 번호

NativeContainer가 폐기되면, NativeContainer 구조체의 모든 사본이 원본 NativeContainer가 유효하지 않다는 것을 인식해야 합니다.원래의 NativeContainer를 폐기한다는 것은 NativeContainer의 데이터를 저장하던 메모리 블록이 할당 해제되었다는 것을 의미합니다.이 경우 NativeContainer의 각 사본에 저장된 데이터에 대한 포인터가 유효하지 않으며, 이를 사용하면 액세스 위반이 발생할 수 있습니다.

AtomicSafetyHandle은 또한 NativeContainer 인스턴스에 대해 무효화되는 중앙 레코드를 가리킵니다.그러나 안전 시스템은 중앙 레코드에 대한 메모리를 할당 해제하지 않으므로 액세스 위반의 위험을 피할 수 있습니다.

대신 각 레코드에는 버전 번호가 포함됩니다.버전 번호의 사본은 해당 레코드를 참조하는 각 AtomicSafetyHandle 내에 저장됩니다.NativeContainer가 폐기되면 Unity는 중앙 레코드에서 버전 번호를 늘리는 Release()를 호출합니다.이후 , 이 레코드는 다른 NativeContainer 인스턴스에 다시 사용할 수 있습니다.

나머지 각각의 AtomicSafetyHandle은 저장된 버전 번호와 중앙 레코드의 버전 번호를 비교하여 NativeContainer가 폐기되었는지 테스트합니다.Unity는 CheckReadAndThrow, CheckWriteAndThrow와 같은 메서드 호출의 일부로 이 테스트를 자동으로 수행합니다.

동적 네이티브 컨테이너의 정적 뷰

동적 네이티브 컨테이너는 NativeList<T>(컬렉션 패키지에서 사용 가능)처럼, 요소를 계속 추가할 수 있는 가변 크기를 가진 컨테이너입니다.이는 변경할 수 없는 고정 크기를 가진 NativeArray<T>와 같은 정적 네이티브 컨테이너와는 대조적입니다.

동적 네이티브 컨테이너를 사용하는 경우 뷰라는 다른 인터페이스를 통해 해당 데이터에 직접 액세스할 수도 있습니다.뷰를 사용하면 데이터를 복사하거나 소유권을 가져가지 않고도 NativeContainer 오브젝트의 데이터에 별칭을 지정할 수 있습니다.뷰의 예로는 네이티브 컨테이너의 데이터에 요소별로 액세스하는 데 사용할 수 있는 열거자 오브젝트와 NativeListNativeArray처럼 취급하는 데 사용할 수 있는 NativeList<T>.AsArray와 같은 메서드가 포함됩니다.

뷰는 일반적으로 동적 네이티브 컨테이너의 크기가 변경되는 경우 스레드에 안전하지 않습니다.네이티브 컨테이너의 크기가 변경되면 Unity는 데이터가 메모리에 저장되는 위치를 재배치하므로 뷰에서 저장하는 모든 포인터가 무효화되기 때문입니다.

보조 버전 번호

동적 네이티브 컨테이너의 크기가 변경되는 상황을 지원하기 위해 안전 시스템에는 AtomicSafetyHandle에 보조 버전 번호가 포함되어 있습니다.이 메커니즘은 버전 관리 메커니즘과 유사하지만 중앙 레코드에 저장된 두 번째 버전 번호를 사용하며, 첫 번째 버전 번호와 독립적으로 증분할 수 있습니다.

보조 버전 번호를 사용하기 위해 UseSecondaryVersion을 사용하여 NativeContainer에 저장된 데이터로 뷰를 구성할 수 있습니다.네이티브 컨테이너의 크기를 변경하거나 기존 뷰를 무효화시키는 작업의 경우 CheckWriteAndThrow를 사용하는 대신 CheckWriteAndBumpSecondaryVersion을 사용하십시오.또한 NativeContainerSetBumpSecondaryVersionOnScheduleWrite를 네이티브 컨테이너에 쓰는 잡이 예약될 때마다 자동으로 뷰를 무효화하도록 설정해야 합니다.

뷰를 생성하고 AtomicSafetyHandle을 이 뷰에 복사할 때는 CheckGetSecondaryDataPointerAndThrow를 사용하여 네이티브 컨테이너의 메모리에 대한 포인터를 뷰에 복사해도 안전한지 확인하십시오.

특수 핸들

임시 네이티브 컨테이너로 작업할 때 사용할 수 있는 두 가지 특수 핸들이 있습니다.

  • GetTempMemoryHandle:Allocator.Temp로 할당된 네이티브 컨테이너에서 사용할 수 있는 AtomicSafetyHandle을 반환합니다.현재 임시 메모리 범위가 종료되면 Unity가 이 핸들을 자동으로 무효화하므로 사용자가 직접 해제하지 않아도 됩니다.특정 AtomicSafetyHandleGetTempMemoryHandle에서 반환한 핸들인지 테스트하려면 IsTempMemoryHandle을 사용하십시오.
  • GetTempUnsafePtrSliceHandle:안전하지 않은 메모리로 지원되는 임시 네이티브 컨테이너에 사용할 수 있는 전역 핸들을 반환합니다.예를 들어, 스택 메모리로부터 구성된 NativeSlice를 들 수 있습니다.이 핸들을 사용하는 컨테이너는 잡으로 전달할 수 없습니다.
커스텀 네이티브 컨테이너 구현
커스텀 NativeContainer 예제