当前位置: 首页 > news >正文

单位建设网站硬件帮别人设计网站的网站吗

单位建设网站硬件,帮别人设计网站的网站吗,网站建设协议一百互联,wordpress 内容不显示专题的第二篇#xff0c;我们聊聊UE4中的多线程的基础设施。UE4中最基础的模型就是FRunnable和FRunnableThread#xff0c;FRunnable抽象出一个可以执行在线程上的对象#xff0c;而FRunnableThread是平台无关的线程对象的抽象。后面的篇幅会详细讨论这些基础设施。 1. FRu…专题的第二篇我们聊聊UE4中的多线程的基础设施。UE4中最基础的模型就是FRunnable和FRunnableThreadFRunnable抽象出一个可以执行在线程上的对象而FRunnableThread是平台无关的线程对象的抽象。后面的篇幅会详细讨论这些基础设施。 1. FRunnable UE4为我们抽象FRunnable的概念让我们指定在线程上运行的一段逻辑过程。该过程通常是一个较为耗时的操作例如文件IO或者是常态为空闲等待(Idle)的循环随时等待新执行命令到来。 FRunnable为我们提供了四个重要的接口 class CORE_API FRunnable { public:// ....virtual bool Init();virtual uint32 Run() 0;virtual void Stop() {}virtual void Exit() {} };Init是对FRunnable对象的初始化它是由FRunnableThread在创建线程对象后进入线程函数的时候立即被FRunnableThread调用的函数并不能由用户自己调用Run是Runnable过程的入口同样也是有FRunnableThread在Init成功后调用Exit是Run正常退出后由FRunnableThread调用进行对FRunnable对象的清理工作Stop是给用户使用的接口当我们觉得必要时停止FRunnable. 例如一个空闲等待的FRunnable的实现 class MyRunnable : public FRunnable { public:MyRunnable(): RunningFlag(false), WorkEvent(FPlatformProcess::GetSynchEventFromPool()){}~MyRunnable(){FPlatformProcess::ReturnSynchEventToPool(WorkEvent);WorkEvent nullptr;}bool Init() override{// ..if(!WorkEvent)return false;RunningFlag.Store(true);}void Run() override{while(RunningFlag.Load()){WorkEvent-Wait(MAX_uint32);if(!RunningFlag.Load())break;// ...}}void Stop() override{if(RunningFlag.Exchange(false))WorkEvent-Trigger();}void Exit() overrdie{// ...RunningFlag.Store(false);}void Notify(){WorkEvent-Trigger();}private:TAtomicbool RunningFlag;FEvent* WorkEvent;// ... };原子变量RunningFlag作为Runnable对象的运行状态的标记所以Run函数的主体就是在RunningFlag为ture的情况无限循环。WorkEvent是其他线程上执行的任务与MyRunnable交互的事件对象通过Notify接口可以唤醒它继续执行。MyRunnable从Wait中醒来时还会检查一次RunningFlag有可能是唤醒它的是Stop接口发出的事件。而Stop的实现会判断一下标识是否Runnable已经退出而不用再次发出事件了。 2. FRunnableThread FRunnable需要依附与一个FRunnableThread对象才能被执行。例如我们如果要执行第一节的空闲等待的Runnable: auto* my_runnable new MyRunnable{};auto* runnable_thread FRunnableThread::Create(my_runnable, IdleWait);FRunnableThread是平台无关的线程对象的抽象它驱动着FRunnable的初始化执行和清理并提供了管理线程对象生命周期线程局部存储亲缘性和优先级等接口。 class FRunnableThread {// ....// Tls 索引static uint32 RunnableTlsSlot;public:// 获取Tls索引static uint32 GetTlsSlot();// 平台无关的创建线程对象接口static FRunnableThread* Create(class FRunnable* InRunnable,const TCHAR* ThreadName,uint32 InStackSize,EThreadPriority InThreadPri,uint64 InThreadAffinityMask);public:// 设置线程优先级virtual void SetThreadPriority( EThreadPriority NewPriority ) 0;// 挂起线程virtual void Suspend( bool bShouldPause true ) 0;// 杀死线程virtual bool Kill( bool bShouldWait true ) 0;// 同步等待线程退出virtual void WaitForCompletion() 0;protected:// 平台相关的线程对象初始化过程virtual bool CreateInternal(FRunnable* InRunnable, const TCHAR* InThreadName,uint32 InStackSize,EThreadPriority InThreadPri, uint64 InThreadAffinityMask) 0; };UE4已经实现了各个平台的线程对象。Win平台使用的是系统Windows的Thread API. 而其他平台是基于pthread不同平台实现上略有不同。通过编译选项包含平台相关的头文件并通过FPlatformProcess类型的定义来选择相应平台的实现。参见FRunnableThread::Create函数 FRunnableThread* FRunnableThread::Create(class FRunnable* InRunnable, const TCHAR* ThreadName,uint32 InStackSize,EThreadPriority InThreadPri, uint64 InThreadAffinityMask) {// ....NewThread FPlatformProcess::CreateRunnableThread();if (NewThread){if (NewThread-CreateInternal(...))// .....}// .... }线程对象的创建需要指定一个FRunnable对象的实例。 FPlatformProcess::CreateRunnableThread就是简单地new一个平台相关的线程对象而真正的初始化时在FRunnableThread::CreateInternal当中完成的。线程平台相关的API差异很大UE4的封装尽可能地让各个平台的实现略有不同。 系统API创建的线程对象都以_ThreadProc作为入口函数。接下来是一系列的平台相关的初始化工作例如设置栈的大小TLS的索引亲缘性掩码获取平台相关的线程ID等。之后就会进入上一节我们提及的FRunnable的初始化流程中了。一个线程创建成功的时序图如下: Win平台的实现中由于API的历史原因需要_ThreadProc的调用约定是STDCALL. 因此Win平台下的_ThreadProc函数是一个转发函数转发给了另外一个CDECL调用约定的函数FRunnableThreadWin::GuardedRun. 3. Runnable or Callable UE4的多线程模型是Runnable和Thread但是有不少C库如标准库是Callable and Thread. 如果使用标准库的std::thread: int main(void) {std::thread t{ [](){ std::cout Hello Thread. } };t.join();return 0; }暂时忽略标准库thread简陋的设施Callable和Runnable这两个模型是可以等价的也就是他们可以相互表达。 例如我们可以用UE4的设施实现类似std::thread的FThreadUE4已经实现了一个: class FThread final : public FRunnable { public:template typename Func, typename ... Argsexplicit FThread(Func f, Args ... args): Callable(create_callable(std::forwardFunc(f), std::forwardArgs(args)...)), Thread(FRunnableThread::Create(this, whatever)){if(!Thread)throw std::runtime_error{ Failed to create thread! };}void join(){Thread-WaitForCompletion();}virtual uint32 Run() override{Callable();return 0;}private:template typename Func, typename ... Argsstatic auto create_callable(Func f, Args ... args) noexcept{// 为了简单起见用了20的特性如果是17标准以下的话用tuple也能办到。// Eat return typereturn [func std::forwardFunc(f), ... args std::forwardArgs(args)](){std::invoke(func, std::forwardArgs(args...));};}private:TFunctionvoid() Callable;FRunnableThread* Thread; };我们还可以用std::thread和一些封装来实现一个的RunnableThread. 下面是一个简单的实现: class RunnableThread { public:explicit RunnableThread(FRunnable* runnable): runnable_(runnable), inited_(false), init_result_(false), thread_(RunnableThread::Run, this){std::unique_lockstd::mutex lock{ mutex_ };cv_.wait(lock, [this](){ return inited_; });}protected:void Run(){auto result runnable_-Init();{std::unique_lockstd::mutex lock{ mutex_ };inited_ true;init_result_ result;}cv_.notify_one();if(result){runnable_-Run();runnable_-Exit();}}private:FRunnable* runnable_;bool inited_;bool init_result_;std::thread thread_;std::mutex mutex_;std::condition_variable cv_; };虽然笔者不喜欢面向对象的设计OOD但UE4的FRunnable和FRunnaableThread实现得确实挺不错。没有很重的框架束缚并且FRunnable也有着跟callable一样的表达能力并且FRunnableThread封装了各个平台线程库几乎所有的功能特性。总体上来说比标准库的thread设施更齐全。 4. 小结 UE4中的多线程模型用一句话概括为: A FRunnable runs on a FRunnableThread. FRunnable是逻辑上的可执行对象的概念的抽象。对于一个具体的可执行对象的实现用户需要实现Init和Exit接口对Runnable需要的系统资源进行申请和释放用户需要实现Run来控制Runnable的执行流程并在需要的情况下实现Stop接口来控制Runnable的退出。 FRunnableThread是UE4提供的平台无关的线程对象的抽象并提供了控制线程对象生命周期和状态的接口。UE4实现了常见所有平台的线程对象实现细节对用户透明。 除此之外本文还讨论了Runnable与Callable两种模型并且它们具有相同的表达能力。 这个系列的下一篇将会讨论FQueuedThreadPool. 它是由FRunnable及FRunnableThread组合实现的用于执行任务队列的线程池。
http://www.huolong8.cn/news/103399/

相关文章:

  • 橙色营销网站城乡建设部网站造价工程师查询
  • 辽宁网站建设哪里好notepad做网站技巧
  • easyui 网站设计移动网站设计心得
  • 建设银行 商户网站打不开全国 网站备案 数量
  • 秦皇岛网站制作公司哪家好深圳全网推广托管
  • 网站游戏网站开发wordpress智能插件
  • 电子商务网站开发附件今天最新新闻国内大事件
  • 简单的网页设计网站网站建设与优化合同
  • 邢台企业网站建设报价wordpress 主机
  • 常州网站建设推荐网站开发计划书封面
  • 网站后台一般是用什么做的argo wordpress 汉化
  • 专业做网站较好的公司怎样通过阿里云建设网站
  • 网站 收录 做301山东人才招聘信息网官网
  • 软件 网站模板上海网站建设高端定制
  • 免费算生辰八字算命大连seo快速排名
  • 公司设计网站定制做汽车网站开题报告的意义
  • 信得过的网站开发推广wordpress免费主题好不好
  • icp许可证对网站的要求中国移动一键登录
  • php做网站访问记录辛集建设局网站
  • 做网站基础建设英文网站费用
  • 商务网站建设策略网站销户说明
  • 枣庄哪里有做网站设计wordpress 登陆不上
  • c 做彩票网站晋江论坛兔区是什么
  • iis 网站乱码成都知名网站建设公司
  • 如何做简易网站设计签名免费名字
  • 榕江网站建设爱尔眼科医院集团
  • 宜昌网站模板wordpress 读取用户信息
  • 门头沟营销型网站建设网站搭建培训
  • 建站模板推荐数据库查询网站模板
  • 黔南州建设局网站鄂州做网站报价