인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

jh park님의 프로필 이미지

작성한 질문수

Unreal GameThread 문의

작성

·

744

0

안녕하세요.

Unreal 공부 중 해결 되지 않는 문제가 있어 문의 드립니다.

  1. FRunnableThread를 생성

  2. Run()함수에서 FSocket 의 Recv함수를 호출

  3. 수신 된 데이터를 활용 해 Level 내 Actor의 상태를 변경

위 행위를 하였을 경우 GameThread가 아니여서 문제라는 오류가 발생 합니다.

언리얼에서 제공하는 GameThread에 함수를 등록하여 호출 할 수 있는 방법 또는

FRunnableThread에서 Actor의 상태를 변경 할 수 있는 방법이 있는지 질문 드립니다.

 

 

IsRunThread = FRunnableThread::Create(this, TEXT("Create Network Thread"));

uint32 FSocket::Run()

{

while (IsRunThread)

{ Recv(PacketData, BufferSize, BytesRead, ESocketReceiveFlags::None); }

..

SpawnActor(...);

}

 

 

답변 1

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다.

Unreal Engine에서 별도의 스레드에서 생성된 FRunnableThread 또는 그밖의 워커 스레드에서 메인 게임 스레드(GameThread)가 아닌 다른 스레드에서 Actor의 상태를 변경하려고 시도하면 동기화 문제로 인해 오류가 발생할 수 있습니다. 이를 해결하기 위해서는 GameThread에서만 Actor 상태를 변경하도록 해야 합니다.

다음 두 가지 방법을 활용하여 메인 게임 스레드에서 작업을 수행할 수 있습니다.

  1. AsyncTask를 사용하여 GameThread에서 작업 실행하기
    AsyncTask를 사용하면 별도의 스레드에서 GameThread에 작업을 예약할 수 있습니다. 이는 일반적으로 Lambda 함수를 통해 이루어지며, 이를 이용하여 워커 스레드에서 GameThread로 작업을 전환할 수 있습니다.
// 워커 스레드에서 GameThread로 작업을 이동하기 위한 코드 예시
AsyncTask(ENamedThreads::GameThread, [this]()
{
    // 이 안에서는 GameThread에서 실행되는 코드입니다.
    // Actor를 스폰하거나 상태를 변경하는 등의 작업을 안전하게 수행할 수 있습니다.
    SpawnActor(...);
});
  1. FGraphEventRef를 사용하여 GameThread에서 태스크 실행하기
    FGraphEventRef를 사용하면 복잡한 태스크 의존성을 처리하는 고급 방식으로, 스레드 간 태스크를 스케줄링하거나 결과를 동기화할 때 유용합니다. TGraphTask를 생성하여 TFunction을 넘겨주고 GameThread에서 실행하도록 할 수 있습니다.
// 워커 스레드에서 GameThread 태스크를 생성하는 코드 예시
FGraphEventRef Task = FFunctionGraphTask::CreateAndDispatchWhenReady([]()
{
    // 이 안에서는 GameThread에서 실행되는 코드입니다.
    // Actor를 스폰하거나 상태를 변경하는 등의 작업을 수행합니다.
}, TStatId(), nullptr, ENamedThreads::GameThread);

두 방법 모두 GameThread에서 실행되도록 구현하여 Actor의 상태를 변경하거나 고유한 인터랙션을 게임에 통합할 수 있습니다.

이러한 방식으로 Actor의 상태를 안전하게 변경할 수 있으며, 메인 게임 스레드와 워커 스레드 간의 동기화 문제를 피할 수 있습니다.

jh park님의 프로필 이미지
jh park
질문자

답변 감사합니다.

 

알려주신 방법으로 정상적으로 GameThread에 Actor의 상태를 변경 할 수 있었습니다.

하지만 TCP 통신을 통해 수신 받은 Actor에 상태에 대해 처리하지 못하는 문제가 발생 하였습니다.

AsyncTask(ENamedThreads::GameThread, [this, PacketData, BytesRead]()

{

});

cline가 동시에 송신하는 3개의 이벤트 메시지에 대해 하나만 처리하는 문제가 발생 하였습니다.

ENamedThreads::GameThread를 ENamedThreads::AnyThread로 변경 시에는 3개의 이벤트 메시지가 정상적으로 수신 되는 것을 확인 할 수 있었지만 Actor의 상태를 변경하게 되면 오류가 발생합니다. 동시에 송신하는 메시지를 정상적으로 처리하는 방법에 대해 질문 드립니다.

감사합니다.

jh park님의 프로필 이미지

작성한 질문수

질문하기