虚幻官方文档:https://docs.unrealengine.com/5.0/en-US/API/Runtime/Core/HAL/FRunnable/

FRunnable

  • “runnable”对象的接口。
  • 可运行对象是在任意线程上“运行”的对象。调用使用模式是Init()、Run()、Exit()。将要“run”这个对象的线程总是使用那些调用语义。它在创建的线程上执行此操作,以便在这些调用的上下文中可以使用任何特定于线程的使用(TLS等)。“runnable”在Init()中完成所有的初始化。
  • 如果初始化失败,线程将停止执行并返回错误代码。如果成功,则在执行真正的线程工作的地方调用Run()。完成后,调用Exit()以允许正确的清理。

 函数

  • void Exit() 退出可运行对象
  • bool Init()  初始化可运行对象。
  • uint32  Run()  运行可运行对象。
  • void Stop() 停止可运行对象。如果请求线程提前终止,则调用此函数。
  • FSingleThreadRunnable GetSingleThreadInterface() 获取在禁用多线程时用于勾选此可运行项的单线程接口指针。

代码流程示意:

自定义基于Runnable的类

// 头文件
#pragma once #include "HAL/Runnable.h"
#include "CoreMinimal.h" /**
*
*/
class MX_API FTestRunnable:public FRunnable
{
public:
FTestRunnable(FString ThreadName,class AActor1* a1) :MyThreadName(ThreadName), A1(a1) {};
virtual bool Init() override;
virtual uint32 Run() override;
virtual void Exit() override; FString MyThreadName;
class AActor1* A1;
protected:
int32 RunCount = 0;
static FCriticalSection CriticalSection;
};
// 源文件
FCriticalSection FTestRunnable::CriticalSection; bool FTestRunnable::Init()
{
UE_LOG(LogTemp, Log, TEXT("%s 初始化!"), *MyThreadName);
//GEngine->AddOnScreenDebugMessage(-1, 20, FColor::Red, TEXT("%s 初始化!"), *MyThreadName);
return IsValid(A1);
} uint32 FTestRunnable::Run()
{
while (IsValid(A1))
{
// 同步锁 如果没有这行代码 最终各个线程运行的总次数将会大于需要的次数
FScopeLock Lock(&CriticalSection);
if (A1->TestCount < A1->TestTarget)
{
A1->TestCount++;
RunCount++;
// 节约资源 每100次打印一次
if (RunCount % 100 == 0)
UE_LOG(LogTemp, Log, TEXT("%s %d"), *MyThreadName, RunCount);
}
else{break;}
}
return 0;
}
void FTestRunnable::Exit()
{
UE_LOG(LogTemp, Log, TEXT("%s 结束运行!执行次数:%d"), *MyThreadName, RunCount);
}

执行线程的类:

// 头文件
// 定义两个变量用于计数
int32 TestCount; UPROPERTY(EditAnywhere)
int32 TestTarget;
// 源文件 用于创建和开启线程 这里我放在了BeginPlay中方便测试
FTestRunnable* Runnable1 = new FTestRunnable(TEXT("线程1"), this);
FTestRunnable* Runnable2 = new FTestRunnable(TEXT("线程2"), this);
FTestRunnable* Runnable3 = new FTestRunnable(TEXT("线程3"), this);
FRunnableThread* RunnableThread1 = FRunnableThread::Create(Runnable1, *Runnable1->MyThreadName);
FRunnableThread* RunnableThread2 = FRunnableThread::Create(Runnable2, *Runnable2->MyThreadName);
FRunnableThread* RunnableThread3 = FRunnableThread::Create(Runnable3, *Runnable3->MyThreadName);

测试结果:这里我设置的线程运行次数为:1000000

UEC++ 多线程(一) FRunnable的更多相关文章

  1. 【UE4 C++ 基础知识】<12> 多线程——FRunnable

    概述 UE4里,提供的多线程的方法: 继承 FRunnable 接口创建单个线程 创建 AsyncTask 调用线程池里面空闲的线程 通过 TaskGraph 系统来异步完成一些自定义任务 支持原生的 ...

  2. UE4 多线程(一)

    UE4中使用多线程的有两种方式,一种方式就是使用FRunnable和FRunnableThread,另一种方式是Task Graph System.Task Graph System有时会占用游戏线程 ...

  3. 《Exploring in UE4》多线程机制详解[原理分析]

    转自:https://zhuanlan.zhihu.com/c_164452593 目录一.概述二."标准"多线程三.AsyncTask系统3.1 FQueuedThreadPoo ...

  4. UE4 Sockets多线程TCP通信

    转自:https://blog.csdn.net/zilisen/article/details/75007447 一.简介 UE4引擎是提供了Sockets模块和Networking模块的,博主在研 ...

  5. UE4 Socket多线程非阻塞通信

    转自:https://blog.csdn.net/lunweiwangxi3/article/details/50468593 ue4自带的Fsocket用起来依旧不是那么的顺手,感觉超出了我的理解范 ...

  6. 【UE4 C++ 基础知识】<14> 多线程——AsyncTask

    概念 AsyncTask AsyncTask 系统是一套基于线程池的异步任务处理系统.每创建一个AsyncTas,都会被加入到线程池中进行执行 AsyncTask 泛指 FAsyncTask 和 FA ...

  7. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  8. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  9. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

随机推荐

  1. arcgis中栅格矢量计算技巧收藏

    ​ ​编辑 一.计算面积 ( 可以帮我们计算小班面积 )添加 AREA 字段,然后右键点击字段列,然后点击 CALCULATE VALUES; ---> 选择 ADVANCED -->把下 ...

  2. Thread类的常用方法_sleep和创建多线程程序的第二种方式_实现Runnable接口

    sleep方法是在Thread类中的一个静态方法,当一个线程调用了sleep方法,被调用的那个线程就会暂时的让出指定时间的CPU执行权,在这段时间也不会参与CPU的调度,当时间到了之后,就会重新回到就 ...

  3. 网络通讯之Socket-Tcp(二)

    网络通讯之Socket-Tcp  分成2部分讲解: 网络通讯之Socket-Tcp(一): 1.如何理解Socket 2.Socket通信重要函数 3.Socket Tcp 调用的基本流程图 4.简单 ...

  4. Identity Server 4资源拥有者密码认证控制访问API

    基于上一篇文章中的代码进行继续延伸,只需要小小的改动即可,不明白的地方可以先看看本人上一篇文章及源码: Identity Server 4客户端认证控制访问API 一.QuickStartIdenti ...

  5. 螣龙安科反入侵:EDR的缺点

    EDR解决方案提供了比传统终结点安全解决方案更高的功能,并且可以增加人员数量,但是这些功能都有不少的缺点. EDR功能付出巨大代价 在过去四年中,虽然产品成本平均每年下降约35%,但即使到今天,产品的 ...

  6. SpringBoot接口 - 如何优雅的写Controller并统一异常处理?

    SpringBoot接口如何对异常进行统一封装,并统一返回呢?以上文的参数校验为例,如何优雅的将参数校验的错误信息统一处理并封装返回呢?@pdai 为什么要优雅的处理异常 如果我们不统一的处理异常,经 ...

  7. 各种Git Bash乱码解决

    乱码情景一: 当使用git log 出现乱码时,修改 %GIT_HOME%\etc\gitconfig 文件,加入如下内容: [gui] encoding = utf-8[i18n] commiten ...

  8. Idea 的Test测试报错:java.lang.IllegalStateException: Failed to load ApplicationContext

    因为在Test里面使用了注解@Autowired 引入来至bean.xml文件的内容 ,而在Test没有没有办法自动引入,需要在Test类上加上注解 @ContextConfiguration(loc ...

  9. Windows下通过dos来编译c语言源代码文件

    笔者阅览过网上许多的推荐,基本上都是推荐cl命令,但是因为笔者是通过dev c++入门的,不想放弃dev所以就强行使用dev来实现在dos下的编译以及运行 编译 注意:这边涉及到环境变量的配置,环境变 ...

  10. 2539-SpringSecurity系列--在有安全验证的情况下做单元测试Test

    在有安全验证的情况下做单元测试Test 版本信息 <parent> <groupId>org.springframework.boot</groupId> < ...