<ruby id="9ue20"></ruby>

  1. 
    

      国产午夜福利免费入口,国产日韩综合av在线,精品久久人人妻人人做精品,蜜臀av一区二区三区精品,亚洲欧美中文日韩在线v日本,人妻av中文字幕无码专区 ,亚洲精品国产av一区二区,久久精品国产清自在天天线
      網易首頁 > 網易號 > 正文 申請入駐

      UE5多線程|FRunnableThread

      0
      分享至


      【USparkle專欄】如果你深懷絕技,愛“搞點研究”,樂于分享也博采眾長,我們期待你的加入,讓智慧的火花碰撞交織,讓知識的傳遞生生不息!

      這是侑虎科技第1908篇文章,感謝作者南京周潤發供稿。歡迎轉發分享,未經作者授權請勿轉載。如果您有任何獨到的見解或者發現也歡迎聯系我們,一起探討。(QQ群:793972859)

      作者主頁:

      https://www.zhihu.com/people/xu-chen-71-65

      UE游戲包與編輯器中都有眾多線程,多線程可以充分利用CPU多核特性,提升游戲表現,而且現代CPU核數越來越多,游戲多線程就更有必要了。

      一、線程類型

      線程可分為專用線程和線程池中線程。

      專用線程為GameThread,RenderThread,StatsThread等,它們各自都干專門的事情,比如GameThread用于驅動游戲邏輯,RenderThread用于渲染,StatsThread用于干性能分析。在事情干完后會進入阻塞狀態,不消耗CPU資源。

      線程池線程包括PoolThread和TaskGraphThread,每個線程用于干多種異步任務。游戲中許多任務并發量大,但持續時間短,比如求解動畫藍圖,每幀都開幾個線程求解,求解完再銷毀線程無疑很浪費。另外有很多瑣碎的多線程任務,單獨為它們開線程也很浪費。因此UE使用了線程池,池中線程會循環利用,不斷執行不同的異步任務,當沒有任務時也處于阻塞狀態。

      使用多線程時,UE已對底層平臺接口進行了封裝,開發者無需關注平臺差異,直接使用UE提供的統一接口即可。

      常用的多線程方式包括:RunnableThread、ThreadPool 和 TaskGraph。這三者在底層線程的實現機制上有所不同,對外提供的接口種類豐富,部分接口還支持通過參數指定所使用的線程實現方式。

      二、FRunnable & FRunnableThread

      基本的線程使用方式為FRunnable與FRunnableThread的組合,用于創建專用線程,比如AsyncLoadingThread與渲染線程等。FRunnable負責邏輯,FRunnableThread負責具體線程,線程承載了邏輯,兩者一一對應,好處是上層邏輯與底層平臺接口分離。

      FRunnable

      FRunnable類本身代表一個抽象的“可運行”對象,只有幾個接口,不涉及線程細節,是我們寫邏輯的地方,理論上可以在任意線程執行。

      接口如下:

      • Init Runnable的初始化,初始化可能成功,可能失敗,失敗會立即返回,線程結束。

      • Run執行邏輯主體,初始化成功后執行。

      • Exit Run中任務執行完后的正常退出接口,執行清理操作。

      • Stop由其他線程調用,用于中途停止該Runnable以及背后的線程,但具體如何停止要我們自己實現。

      • GetSingleThreadInterface,當UE強制單線程模式時,返回用于Tick執行的實例,用的不多。

      上述接口不用我們調用,對應線程創建好后會自動調用。

      示例FAsyncloadingThread:

      該類用于處理異步資源加載,會另開一個線程加載資源,繼承了FRunnable,內部的Thread變量存儲線程。


      Init函數沒做什么,Run函數如下:


      主體是一個while循環,StopTaskCounter是循環退出條件,為Atomic計數器,當未被設置時就不斷處理加載,被設置后即退出。

      Stop函數如下,會設置StopTaskCounter變量:


      創建線程,啟動Run邏輯。

      只需要下面一行代碼即可,詳細會在下文介紹:

      FRunnableThread

      FRunnableThread是平臺線程的抽象,也是基類,與平臺相關的線程操作由多個子類完成,包括:

      • FRunnableThreadWin

      • FRunnableThreadUnix

      • FRunnableThreadApple

      • FRunnableThreadAndroid

      我們不需要繼承和修改這些類,使用即可。

      成員變量:

      • FString ThreadName:線程名。

      • FRunnable* Runnable:對應Runnable。

      • FEvent* ThreadInitSyncEvent:同步的Event。

      • EThreadPriority ThreadPriority:線程優先級,UE自己抽象了幾個枚舉。

      接口:

      • Kill:結束線程,UE建議不要用操作系統的Kill接口,強殺線程會導致泄露和死鎖,應該調用Runnable的Stop方法。

      • WaitForCompletion:忙等,直到線程執行完。

      • Suspend:讓線程掛起或繼續執行。

      • SetThreadPriority:設置線程優先級。

      FRunnableThreadWin

      看下常見的Windows平臺子類如何實現。

      Windows平臺的線程為內核對象,通過HANDLE持有索引,這里的Thread就是底層的線程。


      Kill方法內調用了Runnable的Stop,該函數由我們自己實現,然后可選忙等,最后調用操作系統的CloseHandle方法釋放線程內核對象。


      Windows有TerminateThread方法可以直接結束線程,但平常不推薦調用,有以下幾個原因:

      • 線程函數中C++對象的析構函數不會被執行;

      • 線程棧不會被清理,除非調用TerminateThread的線程結束。這是Windows有意為之,加入其他在運行的線程要引用被“殺死”線程堆棧上的值,就會引起非法內存訪問;

      • DLL通常會在線程終止時收到通知,但TerminateThread會導致DLL收不到通知,從而不執行正常的清理工作。

      Suspend方法調用兩個操作系統接口,掛起和恢復:


      SetThreadPriority方法同樣調用了操作系統接口,只是要做優先級轉換,Windows平臺線程優先級為0-31,31最高。


      Windows中WaitForSingleObject可以實現WaitForCompletion效果:


      三、創建線程

      使用靜態方法Create可創建FRunnableThread和底層線程:


      • InStack為線程棧大小;

      • InThreadPri為線程優先級;

      • InThreadAffinityMask為線程的CPU運行偏好,一般用默認值;

      • InCreateFlags也一般用默認值。

      函數內部首先創建NewThread對象,Windows平臺即FRunnableThreadWin。如果當前設置了強制單線程模式,還可選創建FakeThread,通過Tick驅動執行。


      之后進入CreateInternal函數,調用操作系統接口創建線程。把Runnable屬性設置為傳入的InRunnable,然后把線程相關參數轉化為適配當前操作系統的參數,調用CreateThread Win32API創建線程,線程執行的函數為_ThreadProc。同時注意到CREATE_SUSPENDED參數,線程創建后默認為掛起狀態,執行了后面的ResumeThread,才會讓改線程運行。ThreadInitSyncEvent用于等待線程的Init執行完畢,執行完后調用線程才會繼續。


      _ThreadProc函數先向UE的線程管理類注冊改線程,然后進入FRunnableThreadWin::Run函數,真正開始邏輯,注意這個Run函數和FRunnable的Run毫無關系。

      首先調用Runnable的Inti函數,之后觸發ThreadInitSyncEvent,通知調用線程繼續。然后執行最主要的Runnable->Run,等Run自動結束了,再調用Runnable->Exit做清理。最后返回ExitCode,改線程終止。



      四、使用方式

      Runnable有多種使用方式:

      1. 手動創建FRunnable和FRunnableThread

      可參考前面的FAsyncLoadingThread,適合一個長期任務,而且工作量大。

      2. Async函數

      有時我們只想在其他線程中執行一個短期任務,線程生命周期不長,此時專門創建一個Runnable子類,并手動創建一個Thread有些繁瑣。引擎提供了Async函數,可以只提供我們想要執行的Lambda函數,引擎為我們創建一個Thread,或者從線程池中選擇一個Thread來執行邏輯。

      使用例子:


      第一個參數用于指定線程模式。

      Async函數定義如下:


      第一個參數為線程執行方式,第二個為傳入的函數對象,第三個為執行完的回調。

      線程執行方式Execution有如下幾種取值:

      • TaskGraph:在TaskGraph框架下執行,會在線程池選一個線程,適合短任務。

      • TaskGraphMainThread:與上面類似,但會用主線程。

      • Thread:創建一個新線程執行,適合長任務。

      • ThreadIfForkSate:不知。

      • ThreadPool:在GlobalThreadPool中選一個線程執行。

      • LargeThreadPool:與上面類似,在LargeThreadPool選線程執行,僅Editor下可用。

      這里我們只關注Thread模式,處理分支如下:


      創建了一個TAsyncRunnable對象,把Function和Promise傳入其中,Promise可理解為上面的CompletionCallback,然后通過FRunnableThread::Create接口創建新線程,執行該Runnable。

      TAsyncRunnable是一種特殊類型,它接收一個Function、Promise或Future作為參數。觀察其Run方法:在SetPromise時會執行我們指派的任務。這個FRunnable和FRunnableThread對象是匿名的,外部代碼僅進行New而不Delete,其生命周期由TAsyncRunnable自身托管。具體的清理做法是將刪除操作提交至任務隊列(TaskGraph)。之所以不立即Delete,是因為此時Run函數可能尚未執行完畢,立即Delete自身可能導致異常情況。


      3. AsyncThread函數

      和Async函數類似,內部都用TAsyncRunnable實現,不過它是專門創建匿名線程來執行任務的,因此參數中增加了線程優先級選項,這種用法引擎中不多。


      五、線程同步工具

      多線程環境下線程同步是個問題,UE提供了多種線程同步工具。

      Atomics

      Atomics可以原子的改變一個變量,相比鎖是更輕量的線程同步工具,線程不需要切換狀態,提供更好的性能。從底層視角看,原子操作也是有鎖的,現代多核CPU會通過電路信號鎖Cache的方式來實現原子操作,只是這個過程很快。原子操作是一些多線程安全類型的實現基石。

      使用場景

      常見使用場景為實現多線程安全的計數器,比如SharedPtr里的引用計數,下面的SharedReferenceCount類型就是std::atomic。


      UE引擎提供了幾個類型,是對操作系統和C++ Atomic功能的封裝。

      FPlatformAtomics

      可對一個地址進行原子操作,如Add,Exchange。在不同平臺上會調用各自原子操作接口,Windows為Win32Api的_InterlockedExchange等接口。

      示例


      TAtomic

      類似std::atomic,底層使用FPlatformAtomics實現,提供相似接口。在UE5中,已被標記為DEPRECATED,推薦直接使用std::atomic。

      FThreadSafeCounter

      封裝的線程安全計數器,提供Increment、Decrement等接口,底層同樣使用FPlatformAtomics實現。

      六、鎖

      鎖可以創建一個臨界區,在臨界區內的代碼只允許一個線程執行,其他線程等待。根據臨界區執行時間,以及平臺實現,鎖可能使線程從運行態切換到阻塞態,讓出CPU,這個狀態切換也需要線程從用戶模式切換到內核模式,切換時間大概1000個CPU周期。因此鎖是較重的線程同步工具。

      FCriticalSection

      UE提供了FCriticalSection作為各平臺鎖的封裝。

      Windows平臺底層使用CriticalSection實現,稱為關鍵段,Windows平臺上也有互斥量Mutex,但CriticalSection相比Mutex速度更快。進入臨界區需要調用EnterCriticalSection,其內部會先用原子操作interlocked檢查是否能訪問資源,如果能訪問,就接著運行,這個速度很快。如果不能訪問,通常先Spin忙等一小段時間,若還不能訪問資源,再使用Event內核對象進入阻塞態。當臨界區比較短時,可以避免用戶模式到內核模式的切換。因此Windows平臺會用CriticalSection。

      Linux平臺底層使用pthread_mutex_t實現。

      Windows實現:

      初始化CriticalSection,4000表示未獲取到鎖忙等的CPU周期。


      加鎖


      解鎖


      示例

      通常使用FScopeLock配合FCriticalSection使用,可以通過構造函數與析構函數機制,使作用域內的代碼成為臨界區。


      Event

      Event用于多線程的同步,比如上文介紹的Windows線程創建,主線程在調用CreateThread后,調用ThreadInitSyncEvent->Wait(),等待新線程完成初始化工作,新建線程初始化后執行ThreadInitSyncEvent->Trigger(),通知主線程繼續執行。

      Windows平臺底層使用Event內核對象實現Event。Event有自動重置和手動重置概念,自動重置時,一個線程執行Trigger后,只有一個Wait的線程會被喚醒繼續執行,手動重置時,所有Wait的線程都會被喚醒,后續要手動調用重置函數,才能使Event變為未觸發狀態。通常都使用自動重置。

      FEvent

      UE使用FEvent類型表示一個Event,有Wait、Trigger、Reset等接口。而且Event是內核對象,創建比較昂貴,因此UE使用EventPool來管理這些Event,根據ManualReset分成兩個Pool。

      EventPool接口:


      WindowsRunnableThread中使用方式:


      文末,再次感謝南京周潤發 的分享, 作者主頁:https://www.zhihu.com/people/xu-chen-71-65, 如果您有任何獨到的見解或者發現也歡迎聯系我們,一起探討。(QQ群: 793972859 )。


      近期精彩回顧





      特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。

      Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

      相關推薦
      熱點推薦
      太突然!一天內,兩位NBA球星去世!

      太突然!一天內,兩位NBA球星去世!

      新民晚報
      2026-05-13 18:43:48
      相親要1000萬彩禮的“泡面姐姐”露真容,網友很失望勸她戴上面罩

      相親要1000萬彩禮的“泡面姐姐”露真容,網友很失望勸她戴上面罩

      漢史趣聞
      2026-05-13 10:21:50
      特朗普訪華沒帶夫人,沒給出具體原因!估計是她本人不愿隨叫隨到

      特朗普訪華沒帶夫人,沒給出具體原因!估計是她本人不愿隨叫隨到

      魔都姐姐雜談
      2026-05-13 21:49:17
      英媒:如果阿隆索接任切爾西主帥,有四名皇馬球星可能加盟

      英媒:如果阿隆索接任切爾西主帥,有四名皇馬球星可能加盟

      懂球帝
      2026-05-13 13:04:30
      章子怡“潑墨門”主謀,葉劍英兒媳,離婚后轉戰商圈竟成資本大鱷

      章子怡“潑墨門”主謀,葉劍英兒媳,離婚后轉戰商圈竟成資本大鱷

      財叔
      2026-05-11 08:40:12
      深夜,直線拉升!一則消息,突然引爆!

      深夜,直線拉升!一則消息,突然引爆!

      證券時報
      2026-05-13 23:28:07
      從今天起,中國不再需要日本道歉!這覺醒,來自3500萬亡魂的重量

      從今天起,中國不再需要日本道歉!這覺醒,來自3500萬亡魂的重量

      芳芳歷史燴
      2026-05-13 22:25:25
      廣東一985高校男生偷拍女生裙底,南京那位的教訓還不夠?

      廣東一985高校男生偷拍女生裙底,南京那位的教訓還不夠?

      九方魚論
      2026-05-14 04:25:47
      “性質惡劣!”新西蘭父子在海洋保護區“狂撈”486只鮑魚,企圖販賣!“被判四個月居家監禁! ”

      “性質惡劣!”新西蘭父子在海洋保護區“狂撈”486只鮑魚,企圖販賣!“被判四個月居家監禁! ”

      新西蘭天維網
      2026-05-13 13:05:51
      醫生呼吁:70歲以上老人,寧可吃熱乎饅頭喝稀粥,也別碰這些!

      醫生呼吁:70歲以上老人,寧可吃熱乎饅頭喝稀粥,也別碰這些!

      芹姐說生活
      2026-05-13 19:15:32
      北京狂發18萬綠牌,為何路上仍難覓蹤影?

      北京狂發18萬綠牌,為何路上仍難覓蹤影?

      侃故事的阿慶
      2026-05-14 03:33:42
      英偉達股價續創記錄新高 總市值達到5.5萬億美元

      英偉達股價續創記錄新高 總市值達到5.5萬億美元

      財聯社
      2026-05-13 21:38:14
      秦始皇子孫后代被找到,這四個姓氏都是他的后裔,有你的姓氏嗎?

      秦始皇子孫后代被找到,這四個姓氏都是他的后裔,有你的姓氏嗎?

      興趣知識
      2026-05-11 18:04:48
      A股:人民日報今日重磅發文,請做好準備,周四將迎來新的行情

      A股:人民日報今日重磅發文,請做好準備,周四將迎來新的行情

      云鵬敘事
      2026-05-14 00:00:24
      男子自駕到浙江,出收費站發現手機壞了無法付通行費,浙江收費員當場墊付334元;想留下駕駛證作憑證被拒:安心修好手機,不用著急還款

      男子自駕到浙江,出收費站發現手機壞了無法付通行費,浙江收費員當場墊付334元;想留下駕駛證作憑證被拒:安心修好手機,不用著急還款

      臺州交通廣播
      2026-05-13 16:32:28
      《主角》口碑井噴,本是沖著張嘉益劉浩存來的,卻被48歲女配驚艷

      《主角》口碑井噴,本是沖著張嘉益劉浩存來的,卻被48歲女配驚艷

      冷紫葉
      2026-05-11 23:11:14
      合肥市廬陽區委常委、政法委書記周茂斌接受紀律審查和監察調查

      合肥市廬陽區委常委、政法委書記周茂斌接受紀律審查和監察調查

      環球網資訊
      2026-05-13 18:19:06
      中國國民黨主席鄭麗文預計6月1日訪美,國臺辦回應

      中國國民黨主席鄭麗文預計6月1日訪美,國臺辦回應

      界面新聞
      2026-05-13 14:20:43
      馬斯克點贊宇樹載人機甲:很酷!

      馬斯克點贊宇樹載人機甲:很酷!

      時間財經
      2026-05-13 20:12:22
      蔣友青:我不認識蔣萬安,平時完全沒來往!他們之間發生了什么?

      蔣友青:我不認識蔣萬安,平時完全沒來往!他們之間發生了什么?

      凡人侃史
      2026-05-12 14:37:12
      2026-05-14 07:55:00
      侑虎科技UWA incentive-icons
      侑虎科技UWA
      游戲/VR性能優化平臺
      1575文章數 987關注度
      往期回顧 全部

      科技要聞

      阿里年營收首破萬億,AI終于不再是畫大餅

      頭條要聞

      中東戰火燒痛印度 莫迪六天訪五國要外交“救國”

      頭條要聞

      中東戰火燒痛印度 莫迪六天訪五國要外交“救國”

      體育要聞

      14年半,74萬,何冰嬌沒選那條更安穩的路

      娛樂要聞

      白鹿掉20萬粉,網友為李晨鳴不平

      財經要聞

      美國總統特朗普抵達北京

      汽車要聞

      C級純電轎跑 吉利銀河"TT"申報圖來了

      態度原創

      藝術
      時尚
      旅游
      本地
      軍事航空

      藝術要聞

      這才是真正的“史上最強畢業證”,書法堪比字帖!

      專欄 | 進入心流后,不被洪流裹挾

      旅游要聞

      泰國擬縮短93國游客免簽停留期限,從60天減少至30天

      本地新聞

      用蘇繡的方式,打開江西婺源

      軍事要聞

      美以伊戰爭期間以總理密訪阿聯酋

      無障礙瀏覽 進入關懷版 主站蜘蛛池模板: 免费看A级片| 2022精品福利在线小视频| 人妻少妇中文字幕乱码| 秋霞无码中文| 女子spa高潮呻吟抽搐| 麻豆AV无码久久精品蜜桃久久| 真实国产普通话对白乱子子伦视频 | 亚洲天堂中文在线| 亚洲—本道中文字幕久久66| 国产精品999| 99精品国产在热久久婷婷| 奉化市| 亚洲精品视频免费在线| 亚洲欧美日韩在线码| 亚洲欧美日韩在线码| 久久久中文字幕日本| 超碰色色| 日韩在线一区二区| 亚洲国产成人综合精品| 亚洲视频一区| 国产又色又爽又黄刺激视频| 欧亚一区二区在线观看网站视频| 又大又长粗又爽又黄少妇毛片| 欧洲天堂网| 亚洲精品一区二区制服| 国产高清在线男人的天堂| 成人网站在线进入爽爽爽| 天天爽天天爽天天片a| 亚洲中文字幕在线一区播放| 亚洲老熟女@TubeumTV| 久久精品国产一区二区三 | 中文字幕日韩精品国产| 国产精品香港三级国产av| 成在线人免费视频一区二区三区| 亚洲AV无码一区东京热久久| 尤物视频成人在线视频| 日韩十八不禁| 精品人妻| 午夜诱惑| 亚洲AV综合色无码国产精品四季| 久久国产福利播放|