UE4线程池源码分析和线程池的封装

在游戏客户端开发过程中难免有些任务是需要另外开一个线程来执行的,这些任务的特点是会有一些阻塞操作,它的执行不能影响到游戏线程的正常执行。比如一款网络游戏的客户端,那么网络的收发最好是使用单独的线程来处理,又比如在线更新数据的操作,也最好是使用单独的线程来操作才比较合理。

我在封装线程池之前想了解下UE4的多线程是怎么实现的,所以最近我看了它的源码,刚开始没有找到一个很好的入口,所以看起来云里雾里,还好通过慢慢的啃,总算是看出点门路了,在此分享一下自己的经验,避免其他同行陷入我之前的困境。

UE4采用的是半同步半异步线程池模型,在本文中我使用源码+应用的方式来分析下UE4的线程池,由于UE4是个较复杂的引擎,所以文中如果有出现错误的地方欢迎指正。

我们首先来查看引擎里给的一个线程池的使用例子,代码在Engine\Source\Runtime\Core\Public\Async\AsyncWork.h

class ExampleAutoDeleteAsyncTask : public FNonAbandonableTask
	{
		// 最终会调用此友元类的DoThreadedWork()来执行任务
		friend class FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>;

		int32 ExampleData;

		ExampleAutoDeleteAsyncTask(int32 InExampleData)
		 : ExampleData(InExampleData)
		{
		}

		void DoWork()
		{
			... do the work here
			// 执行真正的任务的地方
		}

		FORCEINLINE TStatId GetStatId() const
		{
			RETURN_QUICK_DECLARE_CYCLE_STAT(ExampleAutoDeleteAsyncTask, STATGROUP_ThreadPoolAsyncTasks);
		}
	};

	
	void Example()
	{
		// start an example job
		(new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(5)->StartBackgroundTask();

		// do an example job now, on this thread
		(new FAutoDeleteAsyncTask<ExampleAutoDeleteAsyncTask>(5)->StartSynchronousTask();
	}


观察Example()函数中并没有哪里显示的创建一个线程池,这是因为官方的这个例子里面使用的UE4在启动的时候自己创建的一个全局线程池,还是上面那个文件,有

FAutoDeleteAsyncTask类的声明,我们需要关注的是Start()函数,它是在Example中的两个Start***中调用的

	void Start(bool bForceSynchronous)
	{
		FPlatformMisc::MemoryBarrier();
		FQueuedThreadPool* QueuedPool = GThreadPool;
		if (bForceSynchronous)
		{
			QueuedPool = 0;
		}
		if (QueuedPool)
		{
			QueuedPool->AddQueuedWork(this);
		}
		else 
		{
			// we aren't doing async stuff
			DoWork();
		}
	}
我们可以看到如果选择的是异步执行的任务,会把自己塞入到GThreadPool的QueuedPool中,其中GThreadPool就是UE4在启动的时候创建的,继续进入到AddQueuedWork()中


                
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值