• 在UE中建立一个最简单的FRunnable所需的代码


    无用的前言

    FRunnable可以在主线程之外的线程中执行代码,当需要并行做某些事的时候会有用。
    虽然在之前的《UE4使用FScopeLock做线程锁》中已顺便创建一个简单的FRunnable的代码,但是不够简单。我想再整理下,得到一个最简单的代码,方便之后用到时直接复制这里。

    目标

    整理出“建立一个最简单的FRunnable所需的代码”。

    1. 定义新的Runnable

    首先,需要继承FRunnable创建自己的子类:

    TestRunnable.h:

    #pragma once
    
    #include "HAL/Runnable.h"
    #include "HAL/RunnableThread.h"
    
    class FTestRunnable : public FRunnable
    {
    
    public:
    	// FRunnable methods.
    	virtual uint32 Run() override;
    	virtual void Stop() override;
    };
    

    想要在这个线程中执行的代码放在Run中。而当在外部终止这个Runnable时,Stop会被调用。

    我这里用于测试的 TestRunnable.cpp 如下:

    #include"TestRunnable.h"
    #include"CoreMinimal.h"
    #include"HAL/PlatformProcess.h"
    
    DEFINE_LOG_CATEGORY_STATIC(LogYaksueTest, Log, All);
    
    uint32 FTestRunnable::Run()
    {
    	//在此处写想要执行的代码:
    	{
    		//作为测试,每1秒打印一次当前时间,执行10次
    		for (int i = 0; i < 10; i++)
    		{
    			FPlatformProcess::Sleep(1.0f);
    			UE_LOG(LogYaksueTest, Warning, TEXT("%s"), *FDateTime::Now().ToString());
    		}
    	}
    
    	return 0;
    }
    
    void FTestRunnable::Stop()
    {
    	UE_LOG(LogYaksueTest, Warning, TEXT("Stop!"));
    }
    

    2. 创建Runnable和RunnableThread

    然后,不仅需要创建FRunnable,还需要创建一个FRunnableThread
    这里我为了方便,直接声明两个 static 指针用于存放他们:

    static FRunnableThread* TestRunnableThread = nullptr;
    static FTestRunnable* TestRunnable = nullptr;
    

    启动时,new出一个Runnable,然后用FRunnableThread::Create创建出RunnableThread:

    TestRunnable = new FTestRunnable();
    TestRunnableThread = FRunnableThread::Create(TestRunnable, TEXT("TestRunnable"), 0, TPri_Normal);
    

    3. 终止时调用Kill

    想要终止时,调用Kill

    TestRunnableThread->Kill();
    
    delete TestRunnableThread;
    TestRunnableThread = nullptr;
    

    效果

    启动后,Runnable就开始执行了,我这里是测试每秒打印1次log。由于不是在主线程中执行的,所以就算用了 FPlatformProcess::Sleep 编辑器也没有卡死。并且,主线程中的操作也不会影响Runnable的执行。
    在这里插入图片描述
    另外要注意的是:我其实在3秒多的时候就调用了Kill,可以看到FTestRunnable::Stop()也确实被调用了。但是Run中的代码还在继续执行(并且此时编辑器卡死)。因此,如果想要终止得更及时,应该需要围绕Stop做些逻辑(比如在Stop中将 bStopping 设置为true,而在Run中检查到 bStopping 为true就立马停止执行后续的代码)

    总结

    在UE中建立一个最简单的FRunnable所需的代码为:

    1. 定义新的FRunnable子类,在Run中放想要这个线程执行的代码,在Stop中放外部终止它时应该被调用的代码。
    2. 启动时,new出一个 Runnable,然后用FRunnableThread::Create创建出 RunnableThread。
    3. 终止时,调用 RunnableThread 的Kill
  • 相关阅读:
    【Hyperledger Fabric 学习】私有数据(Key Concepts: Private data)
    正确使用 Unicode 和 MBCS 字符集
    nginx反向代理,负载均衡配置
    spark踩坑记
    基于JavaSwing开发魔塔小游戏 课程设计 大作业
    python实现中缀表达式转后缀表达式
    【TypeScript】TypeScript的介绍、安装和配置
    CSRF及SSRF详解
    汇编 寻址方式
    设计模式(三)面向对象:贫血和充血模型下的MVC
  • 原文地址:https://blog.csdn.net/u013412391/article/details/126940452