虚幻官方文档:https://docs.unrealengine.com/5.0/en-US/API/Runtime/Core/HAL/FRunnable/
FRunnable
- “runnable”对象的接口。
- 可运行对象是在任意线程上“运行”的对象。调用使用模式是Init()、Run()、Exit()。将要“run”这个对象的线程总是使用那些调用语义。它在创建的线程上执行此操作,以便在这些调用的上下文中可以使用任何特定于线程的使用(TLS等)。“runnable”在Init()中完成所有的初始化。
- 如果初始化失败,线程将停止执行并返回错误代码。如果成功,则在执行真正的线程工作的地方调用Run()。完成后,调用Exit()以允许正确的清理。
函数
- void Exit() 退出可运行对象
- bool Init() 初始化可运行对象。
- uint32 Run() 运行可运行对象。
- void Stop() 停止可运行对象。如果请求线程提前终止,则调用此函数。
- FSingleThreadRunnable GetSingleThreadInterface() 获取在禁用多线程时用于勾选此可运行项的单线程接口指针。
代码流程示意:
自定义基于Runnable的类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| #pragma once
#include "HAL/Runnable.h" #include "CoreMinimal.h"
class MX_API FTestRunnable:public FRunnable { public: FTestRunnable(FString ThreadName,class AActor1* a1) :MyThreadName(ThreadName), A1(a1) {}; virtual bool Init() override; virtual uint32 Run() override; virtual void Exit() override;
FString MyThreadName; class AActor1* A1; protected: int32 RunCount = 0; static FCriticalSection CriticalSection; };
FCriticalSection FTestRunnable::CriticalSection;
bool FTestRunnable::Init() { UE_LOG(LogTemp, Log, TEXT("%s 初始化!"), *MyThreadName); return IsValid(A1); }
uint32 FTestRunnable::Run() { while (IsValid(A1)) { FScopeLock Lock(&CriticalSection); if (A1->TestCount < A1->TestTarget) { A1->TestCount++; RunCount++; if (RunCount % 100 == 0) UE_LOG(LogTemp, Log, TEXT("%s %d"), *MyThreadName, RunCount); } else{break;} } return 0; } void FTestRunnable::Exit() { UE_LOG(LogTemp, Log, TEXT("%s 结束运行!执行次数:%d"), *MyThreadName, RunCount); }
|
执行线程的类:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
int32 TestCount;
UPROPERTY(EditAnywhere) int32 TestTarget;
FTestRunnable* Runnable1 = new FTestRunnable(TEXT("线程1"), this); FTestRunnable* Runnable2 = new FTestRunnable(TEXT("线程2"), this); FTestRunnable* Runnable3 = new FTestRunnable(TEXT("线程3"), this); FRunnableThread* RunnableThread1 = FRunnableThread::Create(Runnable1, *Runnable1->MyThreadName); FRunnableThread* RunnableThread2 = FRunnableThread::Create(Runnable2, *Runnable2->MyThreadName); FRunnableThread* RunnableThread3 = FRunnableThread::Create(Runnable3, *Runnable3->MyThreadName);
|
测试结果:这里我设置的线程运行次数为:1000000
LogTemp:线程2 354000
LogTemp:线程2 354100
LogTemp:线程2 354200
LogTemp:线程1 428600
LogTemp:线程1 428700
LogTemp:线程1 428800
LogTemp:线程1 428900
LogTemp:线程3 216400
LogTemp:线程2 354300
LogTemp:线程2 354400
LogTemp:线程2 354500
LogTemp:线程2 结束运行!执行次数:354573
LogTemp:线程1 结束运行!执行次数:428981
LogTemp:线程3 结束运行!执行次数:216446
PIE: Play in editor total start time 0.178 seconds.