태스크 시스템은 UE::Tasks 네임스페이스에 있습니다. 태스크 시스템을 사용하려면 Tasks/Task.h 라이브러리를 추가해야 합니다. 사용 예시는 Tests/Tasks/TasksTest.cpp 클래스를 참조하면 됩니다.
다음 레퍼런스 표는 태스크 시스템의 핵심 기능의 예시 몇 가지를 보여줍니다.
| 레퍼런스 | 설명 |
|---|---|
TTask<ResultType>() |
실제 태스크의 핸들입니다. 레퍼런스 카운팅으로 태스크의 수명을 관리합니다.
|
TTask<ResultType>::IsValid() |
함수:
태스크 핸들이 태스크를 참조할 경우 true를 반환합니다. 디폴트로 생성된 태스크 핸들은 '비어 있고,' 그에 따라 '유효하지 않습니다.' 태스크는 실행과 동시에 생성됩니다. 예를 들어 다음과 같이 할 수 있습니다.
|
Task<ResultType>::Launch |
비동기 실행을 위해 태스크를 실행합니다. 아래 코드 예시에서는 실행 기능을 태스크에 사용한 뒤 핸들을 반환합니다.
종속된 태스크가 실행되기 전에 다른 태스크부터 완료해야 합니다. 모든 선행 태스크가 완료되면 자동으로 태스크 실행을 예약합니다.
파라미터:
예시:
|
TTask<ResultType>::IsCompleted |
태스크가 완료되었거나 유효하지 않으면 true를 반환합니다.
만약 태스크의 실행이 끝나고 모든 중첩 태스크가 완료되면 태스크가 완료됩니다. 예시:
추가 예시로 |
TTask<ResultType>::Wait |
태스크가 완료되거나 타임아웃되기를 기다렸다가 현재 스레드를 블록합니다. 타임아웃 시 false를 반환합니다. 지정된 타임아웃 값보다 대기가 길어질 수 있습니다.
예시:
선행 태스크에 의해 블록되었거나 워커 스레드에서 아직 선택하지 않아 태스크 실행이 아직 시작되지 않은 경우, 태스크를 '철회'하거나 로컬로 실행할 때까지 대기합니다(인라인). 태스크 실행이 아직 시작되지 않았으므로, 워커 스레드가 태스크를 실행하는 동안 대기 스레드를 블록해야 합니다. 대기 스레드로 태스크를 실행하면 느리지 않고 빠른 프로세스를 진행할 수 있으며 워커 스레드를 침범하지도 않습니다. 태스크 철회 작업은 '딥 태스크 철회'라는 태스크 종속성을 따릅니다. 태스크 실행이 선행 태스크에 의해 차단당할 경우, 태스크 철회는 선행 태스크를 철회하고 다시 실행하여 차단을 풀려고 시도합니다. 테스크 실행이 이미 시작했거나 모종의 이유로 태스크 철회에 실패할 경우 대기 블록으로 돌아갑니다. 예시:
위 샘플은 세 개의 태스크를 실행하며, 여기서 |
TTask<ResultType>::BusyWait |
바쁜 대기(Busy Waiting)는 태스크가 완료되기를 기다리는 동안 관련이 없는 다른 태스크를 실행한다는 뜻입니다. 시스템 처리량은 향상되지만 신중하게 사용해야 합니다. 바쁜 대기는 대기 블록보다 오래 걸릴 수 있으며, 지연시간에 민감한 태스크 체인에 영향을 미칠 수 있습니다. 아래 함수에서 태스크는 대기 중인 태스크가 완료될 때까지 실행 준비를 마친 다른 태스크를 실행합니다. 이 태스크는 BusyWait 반환 후 완료됩니다.
아래 코드 샘플에서 대기 중인 태스크가 완료되었거나 대기 시간이 끝날 때까지 실행 준비를 마친 다른 태스크를 실행합니다. 타임아웃 시 false를 반환합니다. 지정된 타임아웃 값보다 대기가 길어질 수 있습니다. 태스크는 BusyWait에서 true를 반환하면 완료됩니다.
관련이 없는 태스크를 실행하기 전에 바쁜 대기를 사용하면 대기 중인 태스크의 철회를 우선적으로 시도합니다.
|
TTask<ResultType>::GetResult |
태스크에서 실행의 결과로 반환한 오브젝트의 레퍼런스를 반환합니다. 태스크의 바디 실행으로 인해 반환된 값입니다.
태스크가 완료되면 호출 시 결과를 즉시 반환합니다. 완료되지 않으면 태스크를 진행하는 동안 블록합니다. 태스크 오브젝트가 소멸되면 결과 오브젝트도 소멸됩니다. 이때 태스크 오브젝트의 마지막 레퍼런스가 해제됩니다. 태스크가 유효하지 않으면 어서트를 호출합니다. 예시:
|
AddNested() |
주어진 태스크를 '현재' 태스크(부모 태스크)에 '중첩' 상태로 등록합니다. 현재 태스크(Current Task) 는 현재 스레드에서 실행된 태스크입니다. 부모 태스크(Parent Task) 는 모든 중첩 태스크가 완료될 때까지 완료되지 않습니다. 다른 태스크에서 호출되지 않으면 어서트가 호출됩니다.
예시:
|
FTaskEvent
FTaskEvent는 TTask<ResultType> 와 일부 API를 공유합니다. 예를 들어 IsValid(), IsCompleted(), 대기, 바쁜 대기는 API가 같습니다. 이 섹션에서는 FTaskEvent 전용 API만 설명합니다.
| 레퍼런스 태스크 이벤트 | 설명 |
|---|---|
FTaskEvent Constructor |
주어진 디버그 이름으로 파이프 오브젝트를 생성합니다. 디버그 이름은 디버그용으로 사용되어 파이프 오브젝트를 식별합니다.
파이프(Pipe)는 가볍고 복사 및 이동이 불가능한 오브젝트입니다. 파이프 생성은 동적 메모리를 할당하지 않으며, 비용이 많이 드는 프로세스를 수행하지 않습니다. |
FTaskEvent::AddPrerequisites |
다른 태스크 또는 태스크 이벤트를 선행 태스크로 추가합니다. 태스크 이벤트를 트리거하기 전에만 호출할 수 있습니다. 모든 선행 태스크가 완료되고 태스크 이벤트가 트리거될 때만 '완료됨'('시그널링') 상태가 됩니다.
예시:
|
FTaskEvent::Trigger |
태스크 이벤트는 트리거되기 전까지 완료되지 않습니다('논시그널링'). 태스크 이벤트를 트리거해도 꼭 시그널링되는 것은 아니며, 모든 선행 태스크가 완료되고 태스크 이벤트가 트리거될 때만 완료됩니다. 모든 태스크 이벤트는 반드시 트리거되어야 합니다. 아니면 소멸자가 태스크 이벤트가 완료되지 않았다고 어서트를 호출합니다.
|
FPipe
파이프(Pipe)는 가볍고 복사 및 이동이 불가능한 오브젝트입니다. 파이프 생성은 동적 메모리를 할당하지 않으며, 비용이 많이 드는 프로세스를 수행하지 않습니다.
| 레퍼런스 이름 | 설명 |
|---|---|
FPipe constructor |
주어진 디버그 이름으로 파이프 오브젝트를 생성합니다. 디버그 이름은 디버그용으로 사용되어 파이프 오브젝트를 식별합니다.
파이프(Pipe)는 가볍고 복사 및 이동이 불가능한 오브젝트입니다. 파이프 생성은 동적 메모리를 할당하지 않으며, 비용이 많이 드는 프로세스를 수행하지 않습니다. |
FPipe destructor |
파이프에 미완료 태스크가 있는지 확인합니다. 파이프 소멸 시 미완료 태스크가 있으면 안 됩니다. |
HasWork() |
파이프에 미완료 태스크가 있는지 확인합니다. 파이프 소멸 시 미완료 태스크가 있으면 안 됩니다.
|
WaitUntilEmpty() |
이 호출은 파이프의 모든 태스크가 완료될 때까지 블록합니다.
추가 예시는 |
Launch() |
파이프에서 태스크를 실행합니다. 여러 태스크를 동일한 파이프에서 실행할 경우, 태스크를 연속적으로 실행하지 않고 각기 다른 워커 스레드에서 실행할 수 있습니다..
|
IsInContext() |
이 파이프에 속한 태스크에서 호출할 경우 true를 반환합니다. 코드 중에 파이프 태스크에 의해 실행 가능한 범위가 없는 경우처럼 파이프로 보호 중인 공유 리소스에 안전하게 액세스할 수 있는지 확인할 때 사용합니다.
|