{"id":3878,"date":"2022-06-06T16:01:52","date_gmt":"2022-06-06T14:01:52","guid":{"rendered":"https:\/\/store.algosyntax.com\/?post_type=asx-lms-tutorial-cpt&#038;p=3878"},"modified":"2026-03-09T16:29:35","modified_gmt":"2026-03-09T14:29:35","slug":"ue5-multithreading-with-frunnable-and-thread-workflow","status":"publish","type":"asx-lms-tutorial-cpt","link":"https:\/\/store.algosyntax.com\/tutorials\/unreal-engine\/ue5-multithreading-with-frunnable-and-thread-workflow\/","title":{"rendered":"UE5 Multithreading With FRunnable And Thread Workflow"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"3878\" class=\"elementor elementor-3878\" data-elementor-post-type=\"asx-lms-tutorial-cpt\">\n\t\t\t\t<div class=\"elementor-element elementor-element-220886e e-con-full e-flex e-con e-parent\" data-id=\"220886e\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9977860 elementor-widget elementor-widget-text-editor\" data-id=\"9977860\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>An Introductory tutorial to multithreading in Unreal Engine. We discuss how to create multithreaded games in unreal engine, the thread&#8217;s lifecycle, and how to share data between the thread and the main game thread. To archive multithreading in Unreal Engine 5, we make use of the unreal\u00a0 <a href=\"https:\/\/docs.unrealengine.com\/5.0\/en-US\/API\/Runtime\/Core\/HAL\/FRunnable\/\" target=\"_blank\" rel=\"noopener\">FRunnable<\/a> class and the <a href=\"https:\/\/docs.unrealengine.com\/5.0\/en-US\/API\/Runtime\/Core\/HAL\/FRunnableThread\/\" target=\"_blank\" rel=\"noopener\">FRunnableThread<\/a>\u00a0class.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3089f72 elementor-widget elementor-widget-heading\" data-id=\"3089f72\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">How FRunnableThread and FRunnable Classes Work Together<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7078ec4 elementor-widget elementor-widget-text-editor\" data-id=\"7078ec4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>A Thread in unreal engine is an object of the class <strong>FRunnableThread<\/strong>. So when you create a &#8220;thread&#8221; in unreal engine you will be creating an object from the\u00a0 <strong>FRunnableThread<\/strong>\u00a0class.\u00a0\u00a0<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-604fd84 elementor-widget elementor-widget-text-editor\" data-id=\"604fd84\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<ol><li><h3>Create an object of FRunnableThread<\/h3><\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fa8521d elementor-widget elementor-widget-text-editor\" data-id=\"fa8521d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>To\u00a0 <strong>create<\/strong> a thread in unreal engine, we call the static function <a href=\"https:\/\/docs.unrealengine.com\/5.0\/en-US\/API\/Runtime\/Core\/HAL\/FRunnableThread\/Create\/\" target=\"_blank\" rel=\"noopener\">FRunnableThread::Create(). <\/a>\u00a0This function requires a pointer to an object of class <strong>FRunnable:<\/strong><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-014fe35 elementor-widget elementor-widget-text-editor\" data-id=\"014fe35\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>What this means is that we have to create an object of <strong>FRunnable<\/strong> before we create a\u00a0 <strong>FRunnableThread <\/strong>object<strong>.\u00a0<\/strong><\/p><p>\u00a0<\/p><p>You can think of this <strong>FRunnable<\/strong> object as the controller of the <strong>FRunnableThread<\/strong>. A <strong>FRunnableThread<\/strong> requires a controller, a master if you will, that will control what it does, how it does it, and when to die. And this controller must be an object of <strong>FRunnable <\/strong>class or child class.<\/p><p>\u00a0<\/p><p>We will get back to this <strong>create()<\/strong> function and where to call it later. For now, we just wanted you to understand why we are about to create a <strong>FRunnable<\/strong> child class.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-380c40d elementor-widget elementor-widget-text-editor\" data-id=\"380c40d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<ol start=\"2\"><li><h3>Create a pointer to FRunnable<\/h3><\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8729e17 elementor-widget elementor-widget-text-editor\" data-id=\"8729e17\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>To create an object of the unreal <strong>FRunnable<\/strong> class, we must first create a child class of it.<\/p><p>What we want is to create an object of this <strong>child class<\/strong> so that we can have <strong>control<\/strong> over the thread and what it does. In this tutorial we called this child class FMyRunnable. You need to override the following virtual methods from FRunnable:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7a154d8 elementor-widget elementor-widget-code-highlight\" data-id=\"7a154d8\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"code-highlight.default\">\n\t\t\t\t\t\t\t<div class=\"prismjs-default copy-to-clipboard \">\n\t\t\t<pre data-line=\"\" class=\"highlight-height language-cpp line-numbers\">\n\t\t\t\t<code readonly=\"true\" class=\"language-cpp\">\n\t\t\t\t\t<xmp>#include \"CoreMinimal.h\"\r\n\r\nclass FMyRunnable : public FRunnable\r\n{ \r\npublic:\r\n    FMyRunnable();\r\n    \r\n    \/\/override Init,Run and Stop.\r\n    virtual bool Init() override;\r\n\tvirtual uint32 Run() override;\r\n\tvirtual void Exit() override; \r\n\tvirtual void Stop() override;\r\n}<\/xmp>\n\t\t\t\t<\/code>\n\t\t\t<\/pre>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-318bcb9 elementor-widget elementor-widget-text-editor\" data-id=\"318bcb9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<ol start=\"3\"><li><h3>Override the Init, Run, Exit and Stop functions<\/h3><\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2502c4d elementor-widget elementor-widget-text-editor\" data-id=\"2502c4d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>The functions we just overloaded are going to be called automatically by the <strong>FRunnableThread<\/strong> <strong>object<\/strong>.<\/p><p>Remember in the beginning we noted that FRunnableThread requires an object of FRunnable? Well, the reason it requires it, is because these functions are the four main control points of the thread. They are where unreal engine gives the developer a chance to determine a thread&#8217;s behavior during its lifetime.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9e10611 elementor-widget elementor-widget-text-editor\" data-id=\"9e10611\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>They are callback functions that the FRunnableThread will bind to and call at different points of its lifetime to give you a chance to kill it or exchange data with the main thread. So basically you won&#8217;t need to call them yourself when you are multithreading in unreal engine..\u00a0 You just need to define what should happen when they are called.<\/p><p>We will explain what logic is meant to go into these functions. <strong>Keep in mind these functions are for unreal engine to call, not for you to call directly.<\/strong> Keep reading this multithreading tutorial to understand how everything ties together and what functions you CAN and MUST call as the developer.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cfac2ee elementor-widget elementor-widget-heading\" data-id=\"cfac2ee\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Where and When are these functions called<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4c88543 elementor-widget elementor-widget-text-editor\" data-id=\"4c88543\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>You may have noticed we have not yet covered the actual logic that should go into these functions as you write your multithreaded code in unreal engine.\u00a0<\/p><p>\u00a0<\/p><p>This is because you need to understand WHERE and WHEN these virtual functions are called before you can decide what logic\/implementation goes into which.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-fee140f elementor-widget elementor-widget-text-editor\" data-id=\"fee140f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<ol><li><h4>The\u00a0<a href=\"https:\/\/docs.unrealengine.com\/5.0\/en-US\/API\/Runtime\/Core\/HAL\/FRunnable\/Init\" target=\"_blank\" rel=\"noopener\">Init()<\/a> function.<\/h4><\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4604dfe elementor-widget elementor-widget-text-editor\" data-id=\"4604dfe\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Runs in the game thread. <strong>Blocking<\/strong>.<\/p><p>Controls What happens immediately after a thread is created. Consider this your initialization\/constructor for your thread. If you return false in this function, your thread won&#8217;t run.\u00a0<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3d98ad0 elementor-widget elementor-widget-text-editor\" data-id=\"3d98ad0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<ol start=2>\n \t<li>\n<h4>The <a href=\"https:\/\/docs.unrealengine.com\/5.0\/en-US\/API\/Runtime\/Core\/HAL\/FRunnable\/Run\" target=\"_blank\" rel=\"noopener\">Run()\u00a0<\/a>function.<\/h4>\n<\/li>\n<\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7afdee0 elementor-widget elementor-widget-text-editor\" data-id=\"7afdee0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Runs in the new thread. <strong>Nonblocking.<\/strong><\/p><p>The actual function that does the multithreaded work, is the <strong>RUN()\u00a0<\/strong>function.<\/p><p>You can think of the run() function as the equivalent of a main() function but for your thread. It returns an int just like basic c++ programs and should return 0 if successful.\u00a0<\/p><p>Any code that runs in this function will <strong>not<\/strong> block your game thread or eat into your fps(in theory). An exception to this is if you call this function manually from your game thread. Then it will run in your game thread. <strong>Do not call these functions manually<\/strong>.\u00a0 In simplified terms, this function hosts the code that should run in the new thread.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-de30bb3 elementor-widget elementor-widget-text-editor\" data-id=\"de30bb3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<ol start=3>\n \t<li>\n<h4>The <a href=\"https:\/\/docs.unrealengine.com\/5.0\/en-US\/API\/Runtime\/Core\/HAL\/FRunnable\/Exit\/\" target=\"_blank\" rel=\"noopener\">Exit()<\/a> function.<\/h4>\n<\/li>\n<\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d02672e elementor-widget elementor-widget-text-editor\" data-id=\"d02672e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Runs in the new thread. <strong>Nonblocking<\/strong>. What Happens immediately after the thread is done running. i.e After the Run() Function exits. Maybe you want to do some clean-up.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dfe257a elementor-widget elementor-widget-text-editor\" data-id=\"dfe257a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<ol start=4>\n \t<li>\n<h4>The <a href=\"https:\/\/docs.unrealengine.com\/5.0\/en-US\/API\/Runtime\/Core\/HAL\/FRunnable\/Stop\/\" target=\"_blank\" rel=\"noopener\">Stop()<\/a> function.<\/h4>\n<\/li>\n<\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a774635 elementor-widget elementor-widget-text-editor\" data-id=\"a774635\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Runs in the game thread. <strong>Blocking<\/strong>.<\/p><p>This function will run after FRunnableThread::Kill() is called. It will run AT THE SAME TIME as your Run()\u00a0 function but in different threads. The idea is it will write to a <strong>bool<\/strong> that Run() will check, and then Run() will exit its run loop. Usually a while loop.<\/p><p>\u00a0<\/p><p>Normally a thread will exit() on its own when the run function is done but sometimes you may wish to kill it early.<\/p><p>\u00a0<\/p><p>This is the function to put your code that will signal to the run() function;<\/p><p>&#8220;hey, the developer has requested this thread to forcefully exit, so stop loop execution and head to the exit&#8221;.\u00a0<\/p><p>\u00a0<\/p><p>Keep in mind that the EXIT() runs after the RUN() has exited. So the stop() function runs, writing to a bool, and the RUN() function reads the bool. it will then exit, and then the Exit() function will run. . <strong>You do not need to call KILL on a thread that has already exited or finished normally.<\/strong><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-4b12786 elementor-widget elementor-widget-heading\" data-id=\"4b12786\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">The Workflow of multithreading in unreal engine<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-8e6256c elementor-widget elementor-widget-text-editor\" data-id=\"8e6256c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>We have covered the <strong>where<\/strong>, as in which thread and now it&#8217;s time you understand <strong>when<\/strong> these functions are called. We will give you a high-level overview of the process so that you can start multithreading in unreal engine as soon as possible. Here is the calling order:<\/p><ol><li>You call FRunnableThread::Create()<\/li><li>FRunnableThread::Create will then call your FRunnable::Init()<\/li><li>If your FRunnable::Init() returns true, The FRunnable::Run() function will be called.<\/li><li>The FRunnable::Run() will execute. You are now officially running in a separate thread.\u00a0 This function will immediately exit when it&#8217;s done. You can use a while loop to keep it running. We&#8217;ll explain this later.<\/li><li>The FRunnable::Exit() will execute immediately after the Run() function exits.<\/li><li>The FRunnable::Stop will only get called when FRunnableThread::Kill() is called. The Kill function will automatically call your FRunnable::Stop function. We will explain where to call these functions later.<\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-30c903e elementor-widget elementor-widget-text-editor\" data-id=\"30c903e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>At this point, you should have a high level understanding of multithreading in unreal engine and the workflow. That&#8217;s it for now. If you&#8217;re a visual learner , we highly recommend our <strong>Unreal Engine Multithreading For Beginners Course.\u00a0<\/strong>That&#8217;s it for now and we hope we shed some light on what you need to do.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"featured_media":3902,"template":"","asx-lms-tutorial-categories":[58,45],"asx-lms-tutorial-tags":[46],"class_list":["post-3878","asx-lms-tutorial-cpt","type-asx-lms-tutorial-cpt","status-publish","has-post-thumbnail","hentry","asx-lms-tutorial-categories-unreal-c-api","asx-lms-tutorial-categories-unreal-engine","asx-lms-tutorial-tags-cpp","entry","has-media"],"acf":[],"_links":{"self":[{"href":"https:\/\/store.algosyntax.com\/asx-rest\/wp\/v2\/asx-lms-tutorial-cpt\/3878","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/store.algosyntax.com\/asx-rest\/wp\/v2\/asx-lms-tutorial-cpt"}],"about":[{"href":"https:\/\/store.algosyntax.com\/asx-rest\/wp\/v2\/types\/asx-lms-tutorial-cpt"}],"version-history":[{"count":0,"href":"https:\/\/store.algosyntax.com\/asx-rest\/wp\/v2\/asx-lms-tutorial-cpt\/3878\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/store.algosyntax.com\/asx-rest\/wp\/v2\/media\/3902"}],"wp:attachment":[{"href":"https:\/\/store.algosyntax.com\/asx-rest\/wp\/v2\/media?parent=3878"}],"wp:term":[{"taxonomy":"asx-lms-tutorial-categories","embeddable":true,"href":"https:\/\/store.algosyntax.com\/asx-rest\/wp\/v2\/asx-lms-tutorial-categories?post=3878"},{"taxonomy":"asx-lms-tutorial-tags","embeddable":true,"href":"https:\/\/store.algosyntax.com\/asx-rest\/wp\/v2\/asx-lms-tutorial-tags?post=3878"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}