UE4 多线程(一)
UE4中使用多线程的有两种方式,一种方式就是使用FRunnable和FRunnableThread,另一种方式是Task Graph System。Task Graph System有时会占用游戏线程的时间,适合用在简单的计算或者需要开多个线程的情况。FRunnable适用于复杂运算。但是当创建太多线程后,有可能达到CPU的上限,这些线程就会为了抢占CPU的时间而彼此阻碍。UE4提供了FQueuedThreadPool来限制最大的线程数量。
这种方式需要定义一个类继承自FRunnable,并且实现Init,Run,Stop,Exit。还需要一个FRunnableThread对象来创建和销毁线程。
具体代码:
- #pragma once
- #include "CoreMinimal.h"
- #include "Runnable.h"
- #include "RunnableThread.h"
- class TESTTARRAY_API AudioRecordThread : public FRunnable
- {
- public:
- AudioRecordThread(FString threadName);
- ~AudioRecordThread();
- //暂停线程
- void PauseThread();
- //继续线程
- void ContinueThread();
- //停止线程
- void StopThread();
- bool IsThreadPaused();
- bool IsThreadKilled();
- private:
- FRunnableThread* Thread;
- FThreadSafeCounter StopTaskCounter;
- FCriticalSection m_mutex;
- public:
- //override Frunnable Function
- virtual bool Init() override;
- virtual uint32 Run() override;
- virtual void Stop() override;
- virtual void Exit() override;
- private:
- FThreadSafeBool m_Kill;
- FThreadSafeBool m_Pause;
- };
- #include "AudioRecordThread.h"
- #include "Engine.h"
- AudioRecordThread::AudioRecordThread(FString threadName) : StopTaskCounter()
- {
- m_Kill = false;
- m_Pause = false;
- Thread = FRunnableThread::Create(this, *threadName, , TPri_BelowNormal);
- }
- AudioRecordThread::~AudioRecordThread()
- {
- if (Thread)
- {
- delete Thread;
- Thread = nullptr;
- }
- }
- void AudioRecordThread::PauseThread()
- {
- m_Pause = true;
- }
- void AudioRecordThread::ContinueThread()
- {
- m_Pause = false;
- }
- void AudioRecordThread::StopThread()
- {
- Stop();
- if (Thread)
- {
- Thread->WaitForCompletion();
- }
- }
- //需要注意的是在其他线程不能对UObject进行操作,不能使用TimerManager,不能使用DrawDebugLine。
- bool AudioRecordThread::IsThreadPaused()
- {
- return (bool)m_Pause;
- }
- bool AudioRecordThread::IsThreadKilled()
- {
- return (bool)m_Kill;
- }
- bool AudioRecordThread::Init()
- {
- GEngine->AddOnScreenDebugMessage(-, 10.0f, FColor::Yellow, TEXT("AudioRecordThreadInit"));
- return true;
- }
- uint32 AudioRecordThread::Run()
- {
- //使用该函数Sleep
- FPlatformProcess::Sleep(0.03);
- while (StopTaskCounter.GetValue() == && !m_Kill)
- {
- if (m_Pause)
- {
- GEngine->AddOnScreenDebugMessage(-, 10.0f, FColor::Yellow, TEXT("AudioRecordThreadPause"));
- if (m_Kill)
- {
- return ;
- }
- }
- else
- {
- GEngine->AddOnScreenDebugMessage(-, 10.0f, FColor::Yellow, TEXT("AudioRecordThreadLoop"));
- m_mutex.Lock();
- //需要同步处理的内容
- m_mutex.Unlock();
- FPlatformProcess::Sleep(0.01);
- }
- }
- return ;
- }
- void AudioRecordThread::Stop()
- {
- StopTaskCounter.Increment();
- m_Kill = true;
- m_Pause = false;
- GEngine->AddOnScreenDebugMessage(-, 10.0f, FColor::Yellow, TEXT("AudioRecordThreadStop"));
- }
- void AudioRecordThread::Exit()
- {
- GEngine->AddOnScreenDebugMessage(-, 10.0f, FColor::Yellow, TEXT("AudioRecordThreadExit"));
- }
创建线程:
- m_AudioRecordThread = new AudioRecordThread("AudioRecordThread1");
, 构造函数中会用FRunnableThread::Create来创建线程。
停止线程:
- if (m_AudioRecordThread)
- {
- m_AudioRecordThread->StopThread();
- delete m_AudioRecordThread;
- m_AudioRecordThread = nullptr;
- }
在StopThread中会调用Stop来控制相关状态量完成线程循环,Thread->WaitForCompletion(),会使调用StopThread的线程即主线程悬挂,当线程循环完成后继续,继续后删除m_AudioRecordThread对象。需要注意的是这样停止线程会调用两次Stop函数,所以Stop中最好只执行控制线程循环停止的状态量。
使用FPlatformProcess::Sleep(0.03)来等待,避免线程占用过多的资源。
线程锁:
使用m_mutex.Lock();和m_mutex.Unlock();包裹住需要同步的代码即可。
需要注意的是在其他线程不能对UObject进行操作,不能使用TimerManager,不能使用DrawDebugLine。要在游戏线程执行代码可以这样用:
- #include "Async.h"
- ...
- AsyncTask(ENamedThreads::GameThread, []() {
- // code to execute on game thread here
- });
另外我这里使用多线程是做录音相关功能,用到了AudioClient.h这个头文件,因为这个文件用到了windows的东西,所以用在UE4里会报错,所以需要把这个头文件放到CPP里包含,用到的struct使用前置声明。
UE4 多线程(一)的更多相关文章
- [UE4]多线程开关,开启的解决方案
像这样直接获取值就会被警告. 解决方法:定义一个变量speed,然后在“Blueprint Update Animation”事件中赋值给这个变量. 这样就不会被警告了. 另外一种解决方法:就是关掉多 ...
- 《Exploring in UE4》多线程机制详解[原理分析]
转自:https://zhuanlan.zhihu.com/c_164452593 目录一.概述二."标准"多线程三.AsyncTask系统3.1 FQueuedThreadPoo ...
- UE4 Sockets多线程TCP通信
转自:https://blog.csdn.net/zilisen/article/details/75007447 一.简介 UE4引擎是提供了Sockets模块和Networking模块的,博主在研 ...
- UE4 Socket多线程非阻塞通信
转自:https://blog.csdn.net/lunweiwangxi3/article/details/50468593 ue4自带的Fsocket用起来依旧不是那么的顺手,感觉超出了我的理解范 ...
- UE4的多线程
1. 源代码 AsyncWork.h 2. 多线程的使用 参考文档:https://wiki.unrealengine.com/Using_AsyncTasks 当我们需要执行一个需要很长时间的任务时 ...
- 【UE4 C++ 基础知识】<12> 多线程——FRunnable
概述 UE4里,提供的多线程的方法: 继承 FRunnable 接口创建单个线程 创建 AsyncTask 调用线程池里面空闲的线程 通过 TaskGraph 系统来异步完成一些自定义任务 支持原生的 ...
- 【UE4 C++ 基础知识】<13> 多线程——TaskGraph
概述 TaskGraph 系统是UE4一套抽象的异步任务处理系统 TaskGraph 可以看作一种"基于任务的并行编程"设计思想下的实现 通过TaskGraph ,可以创建任意多线 ...
- 【UE4 C++ 基础知识】<14> 多线程——AsyncTask
概念 AsyncTask AsyncTask 系统是一套基于线程池的异步任务处理系统.每创建一个AsyncTas,都会被加入到线程池中进行执行 AsyncTask 泛指 FAsyncTask 和 FA ...
- 《图解UE4渲染体系》Part 1 多线程渲染
上回书<Part 0 引擎基础>说到,我们粗略地知道UE4是以哪些类来管理一个游戏场景里的数据的,但这仅仅是我们开始探索UE4渲染体系的一小步. 本回主要介绍UE4渲染体系中比较宏观顶层的 ...
随机推荐
- linux防火墙之 ufw
Usage: ufw COMMAND Commands: enable enables the firewall 开启ufw防火墙 disable disables the firewall 禁用防火 ...
- 一个IC软件工程师的2017年终工作总结
相比2016年的波澜起伏,2017多了一份平静和清淡.不过,平静的生活下,总有一颗飞向远方的心. 在这一年将近结束的时候,总结一下自己的工作,生活和学习.也顺便展望一下未来的2018,看看有哪些 美好 ...
- Java基础day01
linux:1免费 开源的操作系统,Java主要是服务器端的开发 2与window,目录结构.安全性比后者高 3常用命令 pwd.ls.cd:vi(打开一个记事本若没有就新建一个记事本) 绝对路径:都 ...
- 在macOS上通过pyenv安装和切换多版本Python
1. 安装homebrew 官网 http://brew.sh/index_zh-cn.html 打开终端,在终端中粘贴如下脚本 /usr/bin/ruby -e "$(curl -fsSL ...
- HTTPS、证书与使用Charles抓包
.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font-size: 14.0px; font-family: "Helvetica Neue", & ...
- 关于javascript代码优化的8点建议
前面的话 本文将详细介绍JS编程风格的几个要点 松耦合 当修改一个组件而不需要更改其他组件时,就做到了松耦合 1.将JS从CSS中抽离:不要使用CSS表达式 //不好的做法 .box{width: e ...
- python3之装饰器
1.装饰器 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处 ...
- I/O模型详细解析
内核空间和用户空间:由于操作系统都包括内核空间和用户空间(或者说内核态和用户态),内核空间主要存放的是内核代码和数据,是供系统进程使用的空间.而用户空间主要存放的是用户代码和数据,是供用户进程使用的空 ...
- SAP Fiori应用的三种部署方式
封面图片来自Google搜索,关键字: Fiori Deployment 方式1 On premise环境下以BSP应用作为Fiori应用部署和运行的载体 在SAP成都labs我曾经担任过CRM这几个 ...
- [原创]在Centos7.2上源码安装PHP、Nginx、Zentao禅道
版本 操作系统:CentOS Linux release 7.2.1511 (Core) PHP:5.6.33 Nginx:1.12.2 MySQL:5.6.38(192.168.1.103的Wind ...