对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;
};
- 继承
FRunable
- 重写方法
virtual ~MyRunable() override;
MyRunable::~MyRunable()
{
if (Thread != nullptr)
{
Thread->Kill(true); // 杀死线程, 是否等待线程再杀死,一般先调用Stop()再进行delete
delete Thread;
}
}
// 真正创建线程的地方
// 需要手动调用
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 { }
- 使用自定义的线程类
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,执行MyRunable的Start后创建的线程ID为:ThreadID = ChildValue,则线程的生命周期如下:
![]()