【UE4 C++ 基础知识】<14> 多线程——AsyncTask
阅读原文时间:2023年07月09日阅读:2

概念

  • AsyncTask 系统是一套基于线程池的异步任务处理系统。每创建一个AsyncTas,都会被加入到线程池中进行执行
  • AsyncTask 泛指 FAsyncTaskFAutoDeleteAsyncTask,一般声明为友元函数,FNonAbandonableTask 派生类作为模板
  • FNonAbandonableTask 是要继承的基类,不可被终止的任务,可以看作是任务执行体的抽象

FAsyncTask

  • 模板类
  • DoWork() 实现具体任务,自定义类作为模板参数
  • FAsyncTask 初始化后,默认添加到线程池FQueuedThreadPool。可以指定其他线程池
    • StartBackgroundTask() 将任务扔到线程池中去执行
    • StartSynchronousTask() 直接在当前线程执行
  • EnsureCompletion() 可以等待任务完成
  • 执行结束需要手动停止或删除任务

FAutoDeleteAsyncTask

  • 与 FAsyncTask 类似

  • 执行结束自动删除伍。执行完成后,会通过线程池的 Destroy 函数删除,或者 DoWork 完成后删除

  • FQueuedThreadPool: 虚基类,定义线程池常用的接口。FQueueThreadPoolBase 继承FQueuedThreadPool,实现具体的方法。

  • FQueueThreadPoolBase 维护了多个线程FQueuedThread与多个任务队列IQueuedWork

    • TArray QueuedWork(要被执行的任务)
    • TArray QueuedThreads(空闲的线程)
    • TArray AllThreads(所有的线程)。
  • 线程池里的线程都是FQueuedThread类型,FQueuedThread是继承自FRunnable的线程执行体

  • FRunnableThread 表示线程本身,该类会派生出平台相关的子类

  • FEvent: 虚基类,提供了事件操作的接口,用于线程的挂起/唤醒(Wait()/Trigger())

使用方法

  • SimpleAsyncTask 类

    class  SimpleAsyncTask :FNonAbandonableTask
    {
        FString m_TaskName;
        int32 m_MaxNumber;
        friend class FAsyncTask<SimpleAsyncTask>;
    public:
        // 构造函数
        SimpleAsyncTask(const FString& TaskName, int32 MaxNumber)
            : m_TaskName(TaskName), m_MaxNumber(MaxNumber) {}
        // 析构函数
        ~SimpleAsyncTask()
        {
            UE_LOG(LogTemp, Warning, TEXT("Task[%s] End"), *m_TaskName);
        }
    // 具体任务逻辑执行
    void DoWork()
    {
        UE_LOG(LogTemp, Warning, TEXT("Task[%s] Start"), *m_TaskName);
        int CurrentNum = 0;
        while (CurrentNum &lt; m_MaxNumber)
        {
            CurrentNum++;
            UE_LOG(LogTemp, Warning, TEXT("Task[%s] CurrentNum:%d"), *m_TaskName, CurrentNum);
        }
    }
    
    // 固定写法,本类将作为函数参数
    FORCEINLINE TStatId GetStatId() const
    {
        RETURN_QUICK_DECLARE_CYCLE_STAT(SimpleAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
    }
    };
  • 调用任务的Actor——AAsyncTaskActor

    UFUNCTION(BlueprintCallable)
        void CreateAsyncTask(const FString& TaskName, int32 MaxNumber);
    
    
    void AAsyncTaskActor::CreateAsyncTask(const FString& TaskName, int32 MaxNumber)
    {
        UE_LOG(LogTemp, Warning, TEXT("Task[%s] Created"), *TaskName);
        FAsyncTask<SimpleAsyncTask>* MyTask = new FAsyncTask<SimpleAsyncTask>(TaskName, MaxNumber);
        MyTask->StartBackgroundTask();
    // MyTask-&gt;StartSynchronousTask; 在当前线程执行,可能会导致主线程阻塞
    // MyTask-&gt;IsDone()  可以配合定时器检测是否完成任务
    
    //等待任务完成后,进行手动删除
    MyTask-&gt;EnsureCompletion();
    delete MyTask;
    MyTask = nullptr;
    }
  • AutoDeleteSimpleAsyncTask 类

    class  AutoDeleteSimpleAsyncTask :FNonAbandonableTask
    {
        FString m_TaskName;
        int32 m_MaxNumber;
        friend class FAutoDeleteAsyncTask<AutoDeleteSimpleAsyncTask>;
    public:
        // 构造函数
        AutoDeleteSimpleAsyncTask(const FString& TaskName, int32 MaxNumber)
            : m_TaskName(TaskName), m_MaxNumber(MaxNumber) {}
        // 析构函数
        ~AutoDeleteSimpleAsyncTask()
        {
            UE_LOG(LogTemp, Warning, TEXT("Task[%s] End"), *m_TaskName);
        }
    // 具体任务逻辑执行
    void DoWork()
    {
        UE_LOG(LogTemp, Warning, TEXT("Task[%s] Start"), *m_TaskName);
        int CurrentNum = 0;
        while (CurrentNum &lt; m_MaxNumber)
        {
            CurrentNum++;
            UE_LOG(LogTemp, Warning, TEXT("AutoDeleteTask[%s] CurrentNum:%d"), *m_TaskName, CurrentNum);
        }
    }
    
    // 固定写法,本类将作为函数参数
    FORCEINLINE TStatId GetStatId() const
    {
        RETURN_QUICK_DECLARE_CYCLE_STAT(SimpleAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
    }
    };
  • 调用任务的Actor——AAsyncTaskActor

    UFUNCTION(BlueprintCallable)
        void CreateAutoDeleteAsyncTask(const FString& TaskName, int32 MaxNumber);
    
    
    void AAsyncTaskActor::CreateAutoDeleteAsyncTask(const FString& TaskName, int32 MaxNumber)
    {
        UE_LOG(LogTemp, Warning, TEXT("AutoDeleteTask[%s] Created"), *TaskName);
        // 任务完成后,自动删除
        (new FAutoDeleteAsyncTask<AutoDeleteSimpleAsyncTask>(TaskName, MaxNumber))->StartSynchronousTask();
    }

参考

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章