Unreal Engine 4 —— 多线程任务构建

12 篇文章 0 订阅

这篇博客介绍了UE4中多线程任务的C++构建。

在游戏的主线程中,如果存在一个很复杂的运算,那么游戏很容易造成卡顿。在这篇博客里,我使用查找第N个质数的函数作为范例,并且分别创建了一个在游戏主进程以及新开线程中的调用。


函数构建

新建一个AActor,加入如下函数:

// Header file. 
protected:

    /* Calculates prime numbers in the game thread */
    UFUNCTION(BlueprintCallable, Category = MultiThreading)
    void CalculatePrimeNumbers();

    /* Calculates prime numbers in a background thread */
    UFUNCTION(BlueprintCallable, Category = MultiThreading)
    void CalculatePrimeNumbersAsync();

    /* The max prime number */
    UPROPERTY(EditAnywhere, Category = MultiThreading)
    int32 MaxPrime;

新建一个FuntionLibrary,在其中加入CalculatePrimeNumbers函数,用于计算结果:

// MainFunctionLibrary.cpp

void UMainFunctionLibrary::CalculatePrimeNumbers(int32 UpperLimit)
{
    //Calculating the prime numbers...
    for (int32 i = 1; i <= UpperLimit; i++)
    {
        bool isPrime = true;
        for (int32 j = 2; j <= i / 2; j++)
        {
            if (FMath::Fmod(i, j) == 0)
            {
                isPrime = false;
                break;
            }
        }

        if (isPrime) 
            GLog->Log("Prime number #" + FString::FromInt(i) + ": " + FString::FromInt(i));
    }
}

接着在Actor中添加CalculatePrimeNumbers函数:

void AMultiThreadingActor::CalculatePrimeNumbers()
{
    //Performing the prime numbers calculations in the game thread...
    UMainFunctionLibrary::CalculatePrimeNumbers(MaxPrime);
}

并且添加一个CalculatePrimeNumbersAsync函数的空实现。在编译通过之后,在Actor的继承BP中添加操作如下:

Inputs

Task的创建

提到多线程就一定是Tasks。在这里我们创建一个在另一个线程中执行CalculatePrimeNumbers函数的类。

在这里我们需要新添加一个类继承自FNonAbandonableTask的类(可以阅读引擎源代码查看该类的详细信息)。

class PrimeCalculationAsyncTask : public FNonAbandonableTask
{
    int32 MaxPrime;

public:
    /*Default constructor*/
    PrimeCalculationAsyncTask(int32 MaxPrime)
    {
        this->MaxPrime = MaxPrime;
    }

    /*This function is needed from the API of the engine. 
    My guess is that it provides necessary information
    about the thread that we occupy and the progress of our task*/
    FORCEINLINE TStatId GetStatId() const
    {
        RETURN_QUICK_DECLARE_CYCLE_STAT(PrimeCalculationAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
    }

    /*This function is executed when we tell our task to execute*/
    void DoWork()
    {
        UMainFunctionLibrary::CalculatePrimeNumbers(MaxPrime);
    }
};

RETURN_QUICK_DECLARE_CYCLE_STAT宏函数就是用于处理线程池相关的信息,而DoWork函数则是进行函数的调用。

因此在这里就可以在CalculatePrimeNumbersAsync函数中来进行调用了。需要注意的是我们需要创建一个FAutoDeleteAsyncTask来进行对应的操作,它能够保证在task完成后把自己删除。

void AMultiThreadingActor::CalculatePrimeNumbersAsync()
{
    auto task = new FAutoDeleteAsyncTask<PrimeCalculationAsyncTask>(MaxPrime);
    if (task)
        task -> StartBackgroundTask();
}

如果读者想要了解更多关于UE4中的多线程操作,可以从源代码中的AsyncWork.h开始读起。

<全文完>

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值