FRunnable和FRunnableThread

 
 

FRunnable

FRunnable是一个线程的接口,提供一些基本的函数Init,Run等,配合FRunnableThread创建执行线程。

/**
 * Interface for "runnable" objects.
 *
 * A runnable object is an object that is "run" on an arbitrary thread. The call usage pattern is
 * Init(), Run(), Exit(). The thread that is going to "run" this object always uses those calling
 * semantics. It does this on the thread that is created so that any thread specific uses (TLS, etc.)
 * are available in the contexts of those calls. A "runnable" does all initialization in Init().
 *
 * If initialization fails, the thread stops execution and returns an error code. If it succeeds,
 * Run() is called where the real threaded work is done. Upon completion, Exit() is called to allow
 * correct clean up.
 */
class CORE_API FRunnable
{
public:

	/**
	 * Initializes the runnable object.
	 *
	 * This method is called in the context of the thread object that aggregates this, not the
	 * thread that passes this runnable to a new thread.
	 *
	 * @return True if initialization was successful, false otherwise
	 * @see Run, Stop, Exit
	 */
	virtual bool Init()
	{
		return true;
	}

	/**
	 * Runs the runnable object.
	 *
	 * This is where all per object thread work is done. This is only called if the initialization was successful.
	 *
	 * @return The exit code of the runnable object
	 * @see Init, Stop, Exit
	 */
	virtual uint32 Run() = 0;

	/**
	 * Stops the runnable object.
	 *
	 * This is called if a thread is requested to terminate early.
	 * @see Init, Run, Exit
	 */
	virtual void Stop() { }

	/**
	 * Exits the runnable object.
	 *
	 * Called in the context of the aggregating thread to perform any cleanup.
	 * @see Init, Run, Stop
	 */
	virtual void Exit() { }

	/**
	 * Gets single thread interface pointer used for ticking this runnable when multi-threading is disabled.
	 * If the interface is not implemented, this runnable will not be ticked when FPlatformProcess::SupportsMultithreading() is false.
	 *
	 * @return Pointer to the single thread interface or nullptr if not implemented.
	 */
	virtual class FSingleThreadRunnable* GetSingleThreadInterface( )
	{
		return nullptr;
	}

	/** Virtual destructor */
	virtual ~FRunnable() { }
};

FRunnableThread

继承自FRunnable接口的对象本身并没有执行能力,需要配合FRunnableThread来创建线程,然后执行线程函数。

FRunnableThread通过FRunnableThread::Create来调用对应平台的接口来创建线程,并调用 FRunnable 对象的Init,Run等事件。Create执行之后,对应的线程函数Run立即执行,并没有Start之类的方法。

各个函数的执行顺序是,首先执行Init,然后执行Run,Run执行完毕之后执行Exit。

如果要结束线程,可以调用FRunnableThread的Kill方法。Kill方法仅仅调用了RunnableObject的Stop方法,因此需要手动在Stop方法中将退出信息传递给Run函数,从而结束Run方法。

class MYPROJECT_API MyRunnableObject: public FRunnable
{

public:
	MyRunnableObject();
	virtual ~MyRunnableObject();

	int RunTime = 0;
	bool bIsRunning = false;

	/**
	 * Initializes the runnable object.
	 *
	 * This method is called in the context of the thread object that aggregates this, not the
	 * thread that passes this runnable to a new thread.
	 *
	 * @return True if initialization was successful, false otherwise
	 * @see Run, Stop, Exit
	 */
	virtual bool Init()
	{
		bIsRunning = true;
		UE_LOG(LogTemp, Display, TEXT("Init."));
		return true;
	}

	/**
	 * Runs the runnable object.
	 *
	 * This is where all per object thread work is done. This is only called if the initialization was successful.
	 *
	 * @return The exit code of the runnable object
	 * @see Init, Stop, Exit
	 */
	virtual uint32 Run()
	{
		while (bIsRunning)
		{
			UE_LOG(LogTemp, Display, TEXT("Run %d."), RunTime);
			++RunTime;
			//频繁打印日志会导致游戏线程卡死!
			FPlatformProcess::Sleep(1);
		}	

		return 0;
	}

	/**
	 * Stops the runnable object.
	 *
	 * This is called if a thread is requested to terminate early.
	 * @see Init, Run, Exit
	 */
	virtual void Stop() 
	{
		UE_LOG(LogTemp, Display, TEXT("Kill is called via FRunnableThread, stop now."));
		bIsRunning = false;
	}

	/**
	 * Exits the runnable object.
	 *
	 * Called in the context of the aggregating thread to perform any cleanup.
	 * @see Init, Run, Stop
	 */
	virtual void Exit()
	{
		UE_LOG(LogTemp, Display, TEXT("Run finished."));
	}

};
UCLASS()
class MYPROJECT_API AMyProjectGameModeBase : public AGameModeBase
{
	GENERATED_BODY()
	
public:

	virtual void BeginPlay();

	MyRunnableObject* myRunnableObj;

	FTimerHandle timerHandle;

	FRunnableThread*  myThread;

	UFUNCTION()
	void OnTimer();
};

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

	myRunnableObj = new MyRunnableObject();
	myThread = FRunnableThread::Create(myRunnableObj, TEXT("myRunnableObj"));
	GetWorldTimerManager().SetTimer(timerHandle, this, &AMyProjectGameModeBase::OnTimer, 5.0f);
}

void AMyProjectGameModeBase::OnTimer()
{
	if (myThread)
	{
		myThread->Kill(true);
		delete myRunnableObj;
		delete myThread;
	}
}
LogTemp: Display: Init.
LogTemp: Display: Run 0.
LogTemp: Display: Run 1.
LogTemp: Display: Run 2.
LogTemp: Display: Run 3.
LogTemp: Display: Run 4.
LogTemp: Display: Kill is called via FRunnableThread, stop now.
LogTemp: Display: Run 5.
LogTemp: Display: Run finished.

转载于:https://www.cnblogs.com/haisong1991/p/11544255.html

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值