初始多執行緒-2020-7-14
阿新 • • 發佈:2020-07-14
Runnable執行緒和切換執行緒
首先模擬創造執行緒的過程,建立一個介面類,預留一個函式
// This class does not need to be modified. UINTERFACE(MinimalAPI) class UTaskInterface : public UInterface { GENERATED_BODY() }; /** * */ class ADVANCEPROJECT_API ITaskInterface { GENERATED_BODY() // Add interface functions to this class. This is the class that will be inherited to implement this interface.public: virtual void DoWork(){} };
然後就是現執行緒類,繼承FRunnable
DECLARE_DELEGATE(FThreadDeclare) class ADVANCEPROJECT_API ThreadTask : public FRunnable { public: ThreadTask(); FThreadDeclare* MainThreadDeclare; virtual uint32 Run(); void CreateThread(ITaskInterface* NewTaskInter);~ThreadTask(); private: ITaskInterface* TaskInterface; FRunnableThread* Task_Thread; };
CPP:
ThreadTask::ThreadTask() { TaskInterface=nullptr; }
//新執行緒開啟後,會執行重寫的Run方法 uint32 ThreadTask::Run() { UE_LOG(LogTemp,Log,TEXT("Run")); if (TaskInterface) {
//新執行緒 TaskInterface->DoWork(); //這裡插入一個執行緒方法,在他準備完畢後,會執行繫結的方法,會回到這個方法所規定執行緒,如果他繫結過的話。 FGraphEventRef taskRef = FFunctionGraphTask::CreateAndDispatchWhenReady([&]() { MainThreadDeclare->ExecuteIfBound(); },TStatId(),nullptr,ENamedThreads::GameThread); FTaskGraphInterface::Get().WaitUntilTaskCompletes(taskRef); } return 0; }
//真正意義上的開一個新執行緒 void ThreadTask::CreateThread(ITaskInterface* NewTaskInter) { TaskInterface = NewTaskInter; Task_Thread = FRunnableThread::Create(this,TEXT("HelloWorld"),0,TPri_Normal); } ThreadTask::~ThreadTask() { }
NewInter = new ITaskInterface(); NewTask = new ThreadTask(); //繫結代理,將主執行緒的一個函式繫結給他的代理 NewTask->MainThreadDeclare->BindUObject(this,&AAdvanceProjectGameModeBase::Print_V); //開闢執行緒,執行newtask的run() NewTask->CreateThread(NewInter);
圖例:
在create執行緒前,繫結工作還在主執行緒做
到run這裡,就變成自己的執行緒名了。
然後在切換執行緒部分,在執行函式準備完成之前,依舊還是在我們的執行緒裡工作。
準備完畢,進入代理函式,回到主執行緒
GraphTask執行緒
這四個介面方法為固定形式
#pragma once #include "CoreMinimal.h" class FTaskGraph { private: float _Str; public: static ESubsequentsMode::Type GetSubsequentsMode() { return ESubsequentsMode::TrackSubsequents; } FORCEINLINE TStatId GetStatId() { RETURN_QUICK_DECLARE_CYCLE_STAT(FTaskGraph, STATGROUP_TaskGraphTasks); } void DoTask(ENamedThreads::Type CurrentThread, FGraphEventRef Subsequents) { UE_LOG(LogTemp, Log, TEXT("HelloWorld %f"),_Str); } static ENamedThreads::Type GetDesiredThread() { return ENamedThreads::AnyThread; } FTaskGraph(float NewStr): _Str(NewStr) { } };
//支援構造方法傳遞引數
TGraphTask<FTaskGraph>::CreateTask(NULL, ENamedThreads::GameThread).ConstructAndDispatchWhenReady(7.7f);
AsyncTask執行緒
#pragma once #include "CoreMinimal.h" class FMyAsyncTask : public FNonAbandonableTask { friend class FAsyncTask<FMyAsyncTask>; int32 InstanceInt; public: FMyAsyncTask(int32 NewInt): InstanceInt(NewInt) { } void DoWork() { GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("DoWork %d")); UE_LOG(LogTemp,Log,TEXT("DoWork %d"),InstanceInt); } FORCEINLINE TStatId GetStatId() const { RETURN_QUICK_DECLARE_CYCLE_STAT(FMyAsyncTask,STATGROUP_ThreadPoolAsyncTasks); } };
FAsyncTask<FMyAsyncTask>* MyAsync = new FAsyncTask<FMyAsyncTask>(666);
//選擇是否為順序執行還是非同步執行,這裡是非同步 MyAsync->StartBackgroundTask(); if (MyAsync->IsDone()) { delete MyAsync; MyAsync = nullptr; }