内容纲要

例子:

简单地说就是实现一个 FRunnable ,然后用 FRunnableThread::Create 执行

MyClass.h

#pragma once

#include "CoreMinimal.h"
#include "ThreadTestActor.h"

class THREADTEST_API MyClass : public FRunnable
{
public:
    MyClass(FString threadName, class AThreadTestActor* TestActor);
    ~MyClass();

    //准备工作判定,为真才执行 Run
    virtual bool Init() override;
    virtual uint32 Run() override;
    virtual void Exit() override;

    FString MyThreadName;
    class AThreadTestActor* Tester;

private:
    int WorkCount = 0;

    static FCriticalSection CriticalSection;
};

MyClass.h

#include "MyClass.h"

MyClass::MyClass(FString threadName, class AThreadTestActor* TestActor)
{
    MyThreadName = threadName;
    Tester = TestActor;
};

MyClass::~MyClass()
{
}

bool MyClass::Init()
{
    UE_LOG(LogTemp, Log, TEXT("%s init"), *MyThreadName);
    return IsValid(Tester);
}

uint32 MyClass::Run()
{
    while (IsValid(Tester))
    {
        FPlatformProcess::Sleep(0.1f);
        _sleep(50);
        if (Tester->TestCount < Tester->TestTarget)
        {
            Tester->TestCount++;
            WorkCount++;
        }
        else
        {
            break;
        }
    }

    return 0;
}

void MyClass::Exit()
{
    UE_LOG(LogTemp, Log, TEXT("%s  performed %d operations"), *MyThreadName, WorkCount);
}

AThreadTestActor.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "ThreadTestActor.generated.h"

UCLASS()
class THREADTEST_API AThreadTestActor : public AActor
{
    GENERATED_BODY()

public: 
    // Sets default values for this actor's properties
    AThreadTestActor();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    int TestCount;

    UPROPERTY(EditAnywhere)
    int TestTarget;

};

ThreadTestActor.cpp

#include "ThreadTestActor.h"
#include "MyClass.h"

AThreadTestActor::AThreadTestActor()
{
    PrimaryActorTick.bCanEverTick = true;
    TestCount = 0;
}

void AThreadTestActor::BeginPlay()
{
    Super::BeginPlay();

    // UE_LOG(LogTemp, Log, TEXT("start sleep"));
    // _sleep(3000);
    // UE_LOG(LogTemp, Log, TEXT("end sleep"));

    auto runnable1 = new MyClass(TEXT("Thread 1"), this);
    auto runnable2 = new MyClass(TEXT("Thread 2"), this);
    auto runnableThread1 = FRunnableThread::Create(runnable1, *runnable1->MyThreadName);
    auto runnableThread2 = FRunnableThread::Create(runnable2, *runnable2->MyThreadName);

}

// Called every frame
void AThreadTestActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
}