UnrealEngine4多线程任务构建
来源:
52vr |
责任编辑:传说的落叶 |
发布时间: 2019-06-13 08:39 | 浏览量:
这篇文章介绍了UE4中多线程任务的C++构建。
在游戏的主线程中,如果存在一个很复杂的运算,那么游戏很容易造成卡顿。在这篇文章里,我使用查找第N个质数的函数作为范例,并且分别创建了一个在游戏主进程以及新开线程中的调用。
函数构建
新建一个AActor,加入如下函数:
[代码]:
01 |
// Header file. |
02 |
protected : |
03 |
04 |
/* Calculates prime numbers in the game thread */ |
05 |
UFUNCTION(BlueprintCallable, Category = MultiThreading) |
06 |
void CalculatePrimeNumbers(); |
07 |
08 |
/* Calculates prime numbers in a background thread */ |
09 |
UFUNCTION(BlueprintCallable, Category = MultiThreading) |
10 |
void CalculatePrimeNumbersAsync(); |
11 |
12 |
/* The max prime number */ |
13 |
UPROPERTY(EditAnywhere, Category = MultiThreading) |
14 |
int32 MaxPrime; |
新建一个FuntionLibrary,在其中加入CalculatePrimeNumbers函数,用于计算结果:
[代码]:
01 |
// MainFunctionLibrary.cpp |
02 |
03 |
void UMainFunctionLibrary::CalculatePrimeNumbers(int32 UpperLimit) |
04 |
{ |
05 |
//Calculating the prime numbers... |
06 |
for (int32 i = 1; i <= UpperLimit; i++) |
07 |
{ |
08 |
bool isPrime = true ; |
09 |
for (int32 j = 2; j <= i / 2; j++) |
10 |
{ |
11 |
if (FMath::Fmod(i, j) == 0) |
12 |
{ |
13 |
isPrime = false ; |
14 |
break ; |
15 |
} |
16 |
} |
17 |
18 |
if (isPrime) |
19 |
GLog->Log( "Prime number #" + FString::FromInt(i) + ": " + FString::FromInt(i)); |
20 |
} |
21 |
} |
接着在Actor中添加CalculatePrimeNumbers函数:
[代码]:
1 |
void AMultiThreadingActor::CalculatePrimeNumbers() |
2 |
{ |
3 |
//Performing the prime numbers calculations in the game thread... |
4 |
UMainFunctionLibrary::CalculatePrimeNumbers(MaxPrime); |
5 |
} |
并且添加一个CalculatePrimeNumbersAsync函数的空实现。在编译通过之后,在Actor的继承BP中添加操作如下:
Task的创建
提到多线程就一定是Tasks。在这里我们创建一个在另一个线程中执行CalculatePrimeNumbers函数的类。
在这里我们需要新添加一个类继承自FNonAbandonableTask的类(可以阅读引擎源代码查看该类的详细信息)。
[代码]:
01 |
class PrimeCalculationAsyncTask : public FNonAbandonableTask |
02 |
{ |
03 |
int32 MaxPrime; |
04 |
05 |
public : |
06 |
/*Default constructor*/ |
07 |
PrimeCalculationAsyncTask(int32 MaxPrime) |
08 |
{ |
09 |
this ->MaxPrime = MaxPrime; |
10 |
} |
11 |
12 |
/*This function is needed from the API of the engine. |
13 |
My guess is that it provides necessary information |
14 |
about the thread that we occupy and the progress of our task*/ |
15 |
FORCEINLINE TStatId GetStatId() const |
16 |
{ |
17 |
RETURN_QUICK_DECLARE_CYCLE_STAT(PrimeCalculationAsyncTask, STATGROUP_ThreadPoolAsyncTasks); |
18 |
} |
19 |
20 |
/*This function is executed when we tell our task to execute*/ |
21 |
void DoWork() |
22 |
{ |
23 |
UMainFunctionLibrary::CalculatePrimeNumbers(MaxPrime); |
24 |
} |
25 |
}; |
RETURN_QUICK_DECLARE_CYCLE_STAT宏函数就是用于处理线程池相关的信息,而DoWork函数则是进行函数的调用。
因此在这里就可以在CalculatePrimeNumbersAsync函数中来进行调用了。需要注意的是我们需要创建一个FAutoDeleteAsyncTask来进行对应的操作,它能够保证在task完成后把自己删除。
[代码]:
1 |
void AMultiThreadingActor::CalculatePrimeNumbersAsync() |
2 |
{ |
3 |
auto task = new FAutoDeleteAsyncTask<primecalculationasynctask>(MaxPrime); |
4 |
if (task) |
5 |
task -> StartBackgroundTask(); |
6 |
}</primecalculationasynctask> |
如果读者想要了解更多关于UE4中的多线程操作,可以从源代码中的AsyncWork.h开始读起。
相关文章
网友评论
全部评论:0条
推荐
热门