zoukankan      html  css  js  c++  java
  • UE4的多线程

    1. 源代码

      AsyncWork.h

    2. 多线程的使用

      参考文档:https://wiki.unrealengine.com/Using_AsyncTasks

      当我们需要执行一个需要很长时间的任务时,放在主线程里会导致很卡,把此任务放到其他线程里则会好很多,此时多线程就可以起到关键的作用了。

      在UE4里,我们可以使用FAsyncTask 或者FAutoDeleteAsyncTask。

      使用FAsyncTask 时,我们需要手动停止或删除任务;使用FAutoDeleteAsyncTask时,系统则会自动在任务结束后,删除任务。

      需要先建个继承FNonAbandonableTask的类,如源码中的例子:

    class ExampleAutoDeleteAsyncTask : public FNonAbandonableTask
        {
            friend class FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>;
    
            int32 ExampleData;
    
            ExampleAutoDeleteAsyncTask(int32 InExampleData)
             : ExampleData(InExampleData)
            {
            }
    
            void DoWork()
            {
                ... do the work here
            }
    
            FORCEINLINE TStatId GetStatId() const
            {
                RETURN_QUICK_DECLARE_CYCLE_STAT(ExampleAutoDeleteAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
            }
        };

       然后具体调用就是:

    void Example()
        {
            // start an example job
            (new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(5)->StartBackgroundTask();
    
            // do an example job now, on this thread
            (new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(5)->StartSynchronousTask();
        }

      注意:StartBackgroundTask()是在另一个线程中执行此任务;StartSynchronousTask()是在当前线程中马上执行此任务。

      举个例子:

    .h:
    
    #pragma once
    
    #include "CoreMinimal.h"
    #include "GameFramework/Actor.h"
    #include "Kismet/KismetSystemLibrary.h"
    #include "MyActor.generated.h"
    
    
    UCLASS()
    class ASYNCWORKSTUDY_API AMyActor : public AActor
    {
        GENERATED_BODY()
        
    public:    
        // Sets default values for this actor's properties
        AMyActor();
    
    protected:
        // Called when the game starts or when spawned
        virtual void BeginPlay() override;
    
    public:    
        // Called every frame
        virtual void Tick(float DeltaTime) override;
    
        void TestAsync(FString Content);
    
        //多线程例子
        void Example();
    
    };
    
    class ExampleAutoDeleteAsyncTask : public FNonAbandonableTask
    {
        friend class FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>;
    
        int32 ExampleData;
    
        UObject* Object;
    
        AMyActor* Target;
    
        ExampleAutoDeleteAsyncTask(int32 InExampleData, UObject* InObject, AMyActor* InTarget)
            : ExampleData(InExampleData),
            Object(InObject),
            Target(InTarget)
        {
        }
    
        void DoWork()
        {
            UKismetSystemLibrary::PrintString(Object, FString::FromInt(ExampleData));
    
            //调用AMyactor的测试函数
            if (Target) Target->TestAsync("Success");
        }
    
        FORCEINLINE TStatId GetStatId() const
        {
            RETURN_QUICK_DECLARE_CYCLE_STAT(ExampleAutoDeleteAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
        }
    };
    
    .cpp:
        #include "MyActor.h"
    
    
    // Sets default values
    AMyActor::AMyActor()
    {
         // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
        PrimaryActorTick.bCanEverTick = true;
    
    }
    
    // Called when the game starts or when spawned
    void AMyActor::BeginPlay()
    {
        Super::BeginPlay();
        UKismetSystemLibrary::PrintString(this, "Hello");
        Example();
        
    }
    
    // Called every frame
    void AMyActor::Tick(float DeltaTime)
    {
        Super::Tick(DeltaTime);
        
    }
    
    void AMyActor::TestAsync(FString Content)
    {
        UKismetSystemLibrary::PrintString(this, Content);
    }
    
    void AMyActor::Example()
    {
        //在其他线程里执行此任务
        auto task = new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(10, GetWorld(), this);
        if (task) task->StartBackgroundTask();
        //此任务会在当前线程中马上开始。
        auto task2= new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(15, GetWorld(), this);
        if (task2) task2->StartSynchronousTask();
    }
  • 相关阅读:
    国家语言,语言代码,locale id对应表
    SpringMVC,SpringBoot文件下载
    lombok使用基础教程
    博客园主题修改中用到的css属性
    Hexo next博客添加折叠块功能添加折叠代码块
    IntelIj IDEA运行JUnit Test OutOfMemoryError
    Spring Boot-JPA、Hibernate、Spring data jpa之间的关系
    IntelliJ IDEA-设置字体大小
    win10-mysql卸载干净
    IntelliJ IDEA Check out from git
  • 原文地址:https://www.cnblogs.com/mcomco/p/11316803.html
Copyright © 2011-2022 走看看