【USparkle专栏】如果你深怀绝技,爱“搞点研究”,乐于分享也博采众长,我们期待你的加入,让智慧的火花碰撞交织,让知识的传递生生不息!
这是侑虎科技第1917篇文章,感谢作者南京周润发供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。()
当有持续时间短,又比较杂的异步任务时,可以使用ThreadPool,用固定数量的工作线程执行任务,不每次都创建新线的线线程池会真的创建很多线主要线程池底层复用了TaskGraph的线程,线程池只是逻辑上的概念。
AddQueuedWork函数只需要接受IQueuedWork作为参数,TAsyncQueuedWork只是一个子类,我们可以创建子类,做自定义操作,这样也能指定使用哪个线程池。
类型定义可分为线程池,线. 线程池FQueuedThreadPool:线程池基类,定义了线程池的接口。
FQueuedThread继承自FRunnable,是一个可运行任务的抽象,其Create函数如下。首先创建DoWorkEvent,用于做多线程同步,然后创建一个底层的Thread。线程创建好后进入Run方法,初始没有任务,线程在DoWorkEvent上等待,处于休眠状态。
如果线程池中尚有空闲线,QueuedThreads中有元素,那么把任务分配给其中一个线程即可,这里还有一个细节,QueuedThreads采用栈管理,先进后出,这可以更好利用CPU Cache,因为这个Thread可能刚运行过,同时也可以避免数组中的元素移动。得到Thread后,调用DoWork方法添加任务。
另一种情况是所有线程都在忙碌,QueuedThreads中没有元素,这时只能把InQueuedWork暂存到QueuedWork中,等线程执行完之前任务后再做处理。
线程池中的任务,包装了一个Function对象,DoThreadWork函数中使用给Promise SetValue的形式来执行Function。
UE希望把多线程操作尽量放在TaskGraph里,这样好管理。CPU物理核心数量是有限的,如果TaskGraph和ThreadPool都创建了核心数量的线程,其实在各自管理,两边线程都跑满就会产生更多的CPU调度开销。
其实不需要Create了,因为自己不创建线程,初始化在构造函数里完成,主要任务是获取LowLevelTasks::FScheduler单例。
FQueuedWorkInternalData类包装了一个LowLevelTasks::FTask,FTask用于把QueuedWork包装成TaskGraph里可执行的东西。Retract函数用于取消任务,但线程池场景下不需要考虑取消。
TaskGraph中Worker线程的Run函数会循环获取任务执行,细节放后面TashGraph里看,这里只看一个调用栈。
其中128行执行了异步任务,131行通知FQueuedThreadPoolWrapper任务执行完,可调度下个任务,会在下面介绍。
构造函数如下,主要接受一个线程池作为后台线程池,InMaxConcurrency表示最多同时在后台线程池中执行多少个任务。
WorkPool容器就缓存了已创建的FScheduledWork对象,AllocateWork会首先从中获取,没有再创建,避免性能上的浪费。
文末,再次感谢南京周润发 的分享, 作者主页:, 如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群: 793972859 )。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
极目调查丨四城十余家药店仅一家在售无汞体温计,记者实测:狂甩45次,无汞体温计才降到36摄氏度
一根手机取卡针被炒至300元?二手商家称是“铂金材质”,有人信有人买,官方售后回应
冲上热搜!乔任梁爸爸吃8个死蟹中毒住院;上海专家:大闸蟹死了为何不能吃?网友:想穿点
上海松江一农地有人扎堆“挖银元” 文保部门:已介入处理,将请专家挖掘鉴定
国产AI路由系统开源逆袭!仅用19%成本达到Gemini-2.5-Pro同性能
男子10天内做5次毛发毒检结果有阳有阴,为证清白奔波两年无果;律师:可申请重新鉴定
关键时刻 特朗普、马克龙、斯塔默、默茨通线人在汕头火灾中遇难 幸存家属:生者很坚强
关键时刻 特朗普、马克龙、斯塔默、默茨通线人在汕头火灾中遇难 幸存家属:生者很坚强
IDC太看得起苹果了,预测2026年苹果折叠屏上市就拿下全球22%份额