UE 多线程规范化的使用

FRunable的创建和使用进行规范化操作

// 实际的线程为FRunnableThread类, FRunable只是对FRunnableThread的封装,因此实际线程创建是从FRunnableThread的创建开始的
class **_API MyRunable: public FRunnable
{
public:
    // 构造函数中初始化 一些属性
	MyRunable(args): Stopping(false), Thread(nullptr), ThreadName(name_){}
	
	virtual ~MyRunable() override;

public:
    // 自定义的函数
	void Start();

	virtual bool Init() override;

	virtual uint32 Run() override;

	virtual void Stop() override;

	virtual void Exit() override;

public:
	TQueue<FDroneBaseInfo, EQueueMode::Mpsc> queue;
	
private:
	/** Flag indicating that the thread is stopping. */
	bool Stopping;

	/** The thread object. */
	FRunnableThread* Thread;

	/** The receiver thread's name. */
	FString ThreadName;
};
  1. 继承 FRunable
  2. 重写方法
  • virtual ~MyRunable() override;
MyRunable::~MyRunable()
{
	if (Thread != nullptr)
	{
		Thread->Kill(true); // 杀死线程, 是否等待线程再杀死,一般先调用Stop()再进行delete
		delete Thread;
	}
}
  • void Start();
// 真正创建线程的地方
// 需要手动调用
void MyRunable::Start()
{
	Thread = FRunnableThread::Create(this, *ThreadName, 128 * 1024, TPri_AboveNormal, FPlatformAffinity::GetPoolThreadMask());
}
  • virtual bool Init() override;
// Thread 线程创建完成后,自动调用的方法,用于线程运行前的初始化操作
bool MyRunable::Init()
{
	return true;// 返回True时,Run()才会执行
}
  • virtual uint32 Run() override;
uint32 MyRunable::Run()
{
	while (!Stopping)
	{
		// 循环逻辑
	}

	return 0;
}
  • virtual void Stop() override;
void MyRunable::Stop()
{
	Stopping = true;
}
  • virtual void Exit() override;
virtual void Exit() override { }
  1. 使用自定义的线程类MyRunable
  • 线程的使用
    在上述的定义中大概说明了线程的生命周期,由创建线程(ThreadID = A)创建MyRunable对象RunableInA,在构造函数中初始化信息;然后调用RunableInA->Start(),创建真正的线程;线程创建完成后,自动执行Init()Run();由于在线程A中存在MyRunable的引用RunableInA,因此,可以在线程A中调用RunableInA->Stop()暂停线程的运行;最后在A结束后可以析构RunableInA,结束线程以及删除RunableInA
  • 使用方法
// 在某个BeginPlay中(可以在任意位置,需要根据自己的需求和针对程序设计结构的理解)
MyRunable* RunableInA = new MyRunable(args); // 创建`MyRunable`对象

// 启动线程
RunableInA->Start();

// 暂停线程
RunableInA->Stop();


// 结束线程
RunableInA->Stop();
if(RunableInA)
{
    delete RunableInA;
    RunableInA = nullptr;
}
  • 线程的生命周期
    想要充分利用多线程开发的优势,需要熟悉线程的生命周期,可以使用Windows::GetCurrentThreadId()获取当前的线程ID,假设创建MyRunable的线程ID为:ThreadID = ParentValue,执行MyRunableStart后创建的线程ID为:ThreadID = ChildValue,则线程的生命周期如下:
posted @   Hoonan  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示