`
aigo
  • 浏览: 2645758 次
  • 性别: Icon_minigender_1
  • 来自: 宜昌
社区版块
存档分类
最新评论

[UE4][multi-thread]如何创建和终止线程:FRunnableThread::Create()

阅读更多

关键字:UE4 多线程

原文:https://wiki.unrealengine.com/Multi-Threading:_How_to_Create_Threads_in_UE4

相关文档

FRunnable

https://docs.unrealengine.com/latest/INT/API/Runtime/Core/HAL/FRunnable/index.html

FRunnableThread

https://docs.unrealengine.com/latest/INT/API/Runtime/Core/HAL/FRunnableThread/index.html

 

 

h头文件:

//~~~~~ Multi Threading ~~~
class FPrimeNumberWorker : public FRunnable
{	
	/** Singleton instance, can access the thread any time via static accessor, if it is active! */
	static  FPrimeNumberWorker* Runnable;
 
	/** Thread to run the worker FRunnable on */
	FRunnableThread* Thread;
 
	/** The Data Ptr */
	TArray<uint32>* PrimeNumbers;
 
	/** The PC */
	AVictoryGamePlayerController* ThePC;
 
	/** Stop this thread? Uses Thread Safe Counter */
	FThreadSafeCounter StopTaskCounter;
 
	//The actual finding of prime numbers
	int32 FindNextPrimeNumber();
 
private:
	int32				PrimesFoundCount;
public:
 
	int32				TotalPrimesToFind;
 
	//Done?
	bool IsFinished() const
	{
		return PrimesFoundCount >= TotalPrimesToFind;
	}
 
	//~~~ Thread Core Functions ~~~
 
	//Constructor / Destructor
	FPrimeNumberWorker(TArray<uint32>& TheArray, const int32 IN_PrimesToFindPerTick, AVictoryGamePlayerController* IN_PC);
	virtual ~FPrimeNumberWorker();
 
	// Begin FRunnable interface.
	virtual bool Init();
	virtual uint32 Run();
	virtual void Stop();
	// End FRunnable interface
 
	/** Makes sure this thread has stopped properly */
	void EnsureCompletion();
 
 
 
	//~~~ Starting and Stopping Thread ~~~
 
 
 
	/* 
		Start the thread and the worker from static (easy access)! 
		This code ensures only 1 Prime Number thread will be able to run at a time. 
		This function returns a handle to the newly started instance.
	*/
	static FPrimeNumberWorker* JoyInit(TArray<uint32>& TheArray, const int32 IN_TotalPrimesToFind, AVictoryGamePlayerController* IN_PC);
 
	/** Shuts down the thread. Static so it can easily be called from outside the thread context */
	static void Shutdown();
 
    static bool IsThreadFinished();
};

 

cpp文件:

//***********************************************************
//Thread Worker Starts as NULL, prior to being instanced
//		This line is essential! Compiler error without it
FPrimeNumberWorker* FPrimeNumberWorker::Runnable = NULL;
//***********************************************************
 
FPrimeNumberWorker::FPrimeNumberWorker(TArray<uint32>& TheArray, const int32 IN_TotalPrimesToFind, AVictoryGamePlayerController* IN_PC)
	: ThePC(IN_PC)
	, TotalPrimesToFind(IN_TotalPrimesToFind)
	, StopTaskCounter(0)
	, PrimesFoundCount(0)
{
	//Link to where data should be stored
	PrimeNumbers = &TheArray;

	Thread = FRunnableThread::Create(this, TEXT("FPrimeNumberWorker"), 0, TPri_BelowNormal); //windows default = 8mb for thread, could specify more
}
 
FPrimeNumberWorker::~FPrimeNumberWorker()
{
	delete Thread;
	Thread = NULL;
}
 
//Init
bool FPrimeNumberWorker::Init()
{
	//Init the Data 
	PrimeNumbers->Empty();
	PrimeNumbers->Add(2);
	PrimeNumbers->Add(3);
 
	if(ThePC) 
	{
		ThePC->ClientMessage("**********************************");
		ThePC->ClientMessage("Prime Number Thread Started!");
		ThePC->ClientMessage("**********************************");
	}
	return true;
}
 
//Run
uint32 FPrimeNumberWorker::Run()
{
	//Initial wait before starting
	FPlatformProcess::Sleep(0.03);
 
	//While not told to stop this thread 
	//		and not yet finished finding Prime Numbers
	while (StopTaskCounter.GetValue() == 0 && ! IsFinished())
	{
		PrimeNumbers->Add(FindNextPrimeNumber());
		PrimesFoundCount++;
 
		//***************************************
		//Show Incremental Results in Main Game Thread!
 
		//	Please note you should not create, destroy, or modify UObjects here.
		//	  Do those sort of things after all thread are completed.
 
		//	  All calcs for making stuff can be done in the threads
		//	     But the actual making/modifying of the UObjects should be done in main game thread.
		ThePC->ClientMessage(FString::FromInt(PrimeNumbers->Last()));
		//***************************************
 
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
		//prevent thread from using too many resources
		//FPlatformProcess::Sleep(0.01);
		//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	}
 
	//Run FPrimeNumberWorker::Shutdown() from the timer in Game Thread that is watching
        //to see when FPrimeNumberWorker::IsThreadFinished()
 
	return 0;
}
 
//stop
void FPrimeNumberWorker::Stop()
{
	StopTaskCounter.Increment();
}
 
FPrimeNumberWorker* FPrimeNumberWorker::JoyInit(TArray<uint32>& TheArray, const int32 IN_TotalPrimesToFind, AVictoryGamePlayerController* IN_PC)
{
	//Create new instance of thread if it does not exist
	//		and the platform supports multi threading!
	if (!Runnable && FPlatformProcess::SupportsMultithreading())
	{
		Runnable = new FPrimeNumberWorker(TheArray,IN_TotalPrimesToFind,IN_PC);			
	}
	return Runnable;
}
 
void FPrimeNumberWorker::EnsureCompletion()
{
	Stop();
	Thread->WaitForCompletion();
}
 
void FPrimeNumberWorker::Shutdown()
{
	if (Runnable)
	{
		Runnable->EnsureCompletion();
		delete Runnable;
		Runnable = NULL;
	}
}
 
bool FPrimeNumberWorker::IsThreadFinished()
{
	if(Runnable) return Runnable->IsFinished();
	return true;
}
int32 FPrimeNumberWorker::FindNextPrimeNumber()
{
	//Last known prime number  + 1
	int32 TestPrime = PrimeNumbers->Last();
 
	bool NumIsPrime = false;
	while( ! NumIsPrime)
	{
		NumIsPrime = true;
 
		//Try Next Number
		TestPrime++;
 
		//Modulus from 2 to current number - 1 
		for(int32 b = 2; b < TestPrime; b++)
		{
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
			//prevent thread from using too many resources
			//FPlatformProcess::Sleep(0.01);
			//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
			if(TestPrime % b == 0) 
			{
				NumIsPrime = false;
				break;
				//~~~
			}
		}
	}
 
	//Success!
	return TestPrime;
}

 

以上是完成了一个继承自FRunnable的自定义类,那么如何用这个类启动线程:

1,这个例子需要一个数组,那么现在头文件中定义一个测试用的变量

//In the .h for the player controller
// this is the actual data
TArray<uint32> PrimeNumbers;

 2,创建并启动线程:

//player controller .cpp
//Multi-threading, returns handle that could be cached.
//		use static function FPrimeNumberWorker::Shutdown() if necessary
FPrimeNumberWorker::JoyInit(PrimeNumbers, 50000, this);

 

补充:

结束终止线程

 

void FPrimeNumberWorker::EnsureCompletion()  
{  
    Stop();  
    Thread->WaitForCompletion();  
}
 

 

 

分享到:
评论

相关推荐

    5G技术与标准介绍----第6部分:4G与5G共存与互操作-20180623

    - **上下文与会话信息传递**:在互操作过程中,源侧和目标侧核心网通过N26接口传递UE的上下文和会话信息,并将UE上下文和会话资源切换到目标侧,确保IP地址和业务连续性不受影响。 ##### 无N26接口的互操作方案 - ...

    5G技术与标准介绍----第3部分:5G网络技术之接入网架构与接口介绍

    为了适应5G多样化的应用场景和更高的性能需求,5G RAN架构引入了**CU-Centralized Unit(集中单元)**和**DU-Distributed Unit(分布单元)**的概念,实现了功能上的分离和优化。 - **CU**: 集中单元负责处理非实时的...

    ios 自带表情 转义字符实现

    实际上,Objective-C本身并不直接支持`\ue415`这样的转义字符格式,但可以通过一些额外的处理将其转换成对应的Unicode字符。 #### 五、更多表情示例 在实际开发中,可能会需要使用到更多的表情符号。下面列举了...

    Python库 | ue4cli-0.0.18-py2.py3-none-any.whl

    Python库“ue4cli-0.0.18-py2.py3-none-any.whl”是一个专门为Unreal Engine 4(UE4)提供命令行工具的模块,它支持Python 2和3版本,使得开发者可以通过命令行接口进行UE4相关的开发工作。这个库的目的是为了简化UE...

    Python库 | conan_ue4cli-0.0.5-py3-none-any.whl

    `conan_ue4cli`将Conan的强大功能与UE4的开发流程相结合,使得UE4开发者可以更轻松地管理他们的项目依赖,包括第三方库的安装、更新和版本控制。 在实际使用中,`conan_ue4cli`提供的命令行工具允许用户执行以下...

    5G技术与标准介绍----第4部分:5G新空口之物理层技术_20180623(简化)

    4. **敏捷性与高效性**:为了提高网络响应速度和效率,NR采用了灵活的双工机制、多址技术、多天线技术等多种手段。 #### 帧结构设计 - **定时单位**:NR采用10毫秒为一个无线帧的基本单位,每个无线帧又分为10个子...

    java面试知识

    ### Java面试知识详解 #### 基础篇 ...- **线程状态**:新建、就绪、运行、阻塞、终止。 - **同步机制**:synchronized关键字、ReentrantLock等。 ##### Ajax请求Session超时问题 - **解决方法**: - 设置...

    UE4 API-SDK

    8. **AI行为树**:UE4的BehaviorTree系统为非玩家角色(NPC)提供了行为控制,开发者可以通过API创建和编辑行为树。 9. **音频系统**:AudioComponent API允许添加和控制声音播放,包括3D音效、音乐和环境声音。 ...

    building-ue4-dedicated-server-blog-1:用于使用AWS和Docker构建和托管Unreal Engine 4专用服务器的源代码

    building-ue4-dedicated-server-blog-1:用于使用AWS和Docker构建和托管Unreal Engine 4专用服务器的源代码

    UE快捷键大全.pdf

    根据提供的文档内容,以下是关于“UE快捷键大全”的知识点汇总,这些快捷键主要应用于某种未明确定义的编辑器或开发环境(UE,可能是指Unreal Engine或其他特定软件),它们在软件的不同功能模块中用于提高用户的...

    ue4-docker:虚幻引擎4的Windows和Linux容器

    ue4-docker Python软件包包含一组Dockerfile和随附的构建基础结构,可用于为Epic Games的构建Docker映像。 这些图像还整合了 , 和的基础,以促进各种用例。 主要功能包括: 支持虚幻引擎4.19.0及更高版本。 ...

    TD网优手册-无线参数篇

    - **作用**:根据UE的具体需求动态调整发射功率,提高系统容量和服务质量。 ##### 4. 移动性管理类 **4.1 小区选择/重选参数** - **定义**:包括Qrxlevmin、Snonintrasearch等。 - **作用**:决定UE如何选择最佳...

    UE4在VS2013中各个编译配置代表意义

    为了更好地管理和编译大型项目,UE4引入了一种名为UnrealBuildTool的工具,该工具能够有效地处理各种复杂的工程构建任务。 #### 二、UnrealBuildTool简介 UnrealBuildTool(UBT)是一种自动化构建工具,它通过解析...

    java面试总结

    - **会话层**: 控制会话的建立和终止。 - **表示层**: 数据格式转换和加密解密。 - **应用层**: 提供应用程序间通信。 #### 二十二、线程和进程的区别 - **进程**: 操作系统进行资源分配和调度的基本单位。 - **...

    UE4第一人称射击游戏制作教程.pdf

    UE4是一款强大的游戏开发引擎,它提供了丰富的工具和资源,使得初学者也能创建出专业级别的游戏。以下是制作第一人称射击游戏的详细步骤,包括关键知识点和实践技巧。 一、创建第一人称蓝图 1-1 项目资源准备: 在...

    虚幻4UE4程序游戏解包

    - **模型与动画**:`.fbx`、`.skel`等文件用于导入3D模型,`.anim`和`.animblueprint`用于创建和编辑角色动画。 3. **解包过程** - **反编译工具**:为了解包`.uasset`文件,你需要使用特定的工具,如UnrealPak或...

    UE4刚体碰撞视频教程

    ### UE4刚体碰撞视频教程知识点详解 #### 一、UE4(Unreal Engine 4)简介 UE4,即Unreal Engine 4,是由Epic Games开发的一款强大的游戏开发引擎。它支持跨平台的游戏开发,包括PC、移动设备、主机平台等。UE4以...

    士兵-塔-防御-UE4:用UE4制作的3D塔防游戏

    士兵塔防UE4士兵塔防3D描述: 该游戏是由UE 4驱动的3D塔防游戏,由UE 4.22制作。 这是一个由 )和 )制作的个人学习项目。游戏玩法: 在地图周围的岩石上放置炮塔以杀死敌人。 小心-他们每波都会带来更大的数量和更...

    UE4-DDC-Settings-Tool:此工具允许开发人员为其UE4项目配置本地DDC设置和共享DDC设置

    DDC设置工具该工具允许开发人员为其UE4项目配置“本地DDC设置”和“共享DDC设置”。其他来源您可以从Unreal Engine Marketplace获得针对4.24、4.25或4.26的打包版本:联系在推特上关注我: 它是如何工作的? 编辑器...

    深入浅出UE4网络 - Leonhard

    UE4提供了多种工具和技术来帮助开发者诊断和优化网络性能,如压缩数据包、智能选择需要复制的数据等。 通过以上概述可以看出,UE4在网络同步方面提供了强大而灵活的功能,支持从简单的同步需求到复杂的多人游戏逻辑...

Global site tag (gtag.js) - Google Analytics