I'm rather confused. Looking at the wiki documentation of spawn(), many things confuse me;
Spawn
spawn (f) or Spawn (f)
Executes function f after thread next yields.
Wait, what does that mean? What is the definition of 'next thread'? How/when will it yield? I assume they don't mean the kind of thread hanging off my sock?
An alternative to this is coroutines. Spawned functions and coroutines aren't used in the same way. Spawn is used to delay the execution of a functions until the thread yields while coroutines are used to run code immediately on a separate thread.
Still don't know what they mean by all that.
On the corountine manipulation page, the wiki says;
Note: ROBLOX also provides a function to create threads that may be used in replace of coroutines if creating a new thread is the only goal.
. . . Yet the other wiki page just said they're different.
So what exactly is the Spawn()
function, what is it used for, and how is it different than corountines?
A thread is a group of computer instructions that can be executed by a task scheduler, in particular Lua's thread task scheduler. In simple words, it is a block of code that runs in serial.
Multithreading is the ability to send multiple threads out to the scheduler and have it execute them simultaneously. It is an important part of parallel computing. When you create a new thread, that thread will seem to run at the same time as the rest of the code. This can be particularly useful for when you want to run processes that may take a long time, or perhaps even infinite time, side by side, such as important game loops.
spawn(function() while true do print("Loop a", tick()) --> prints every half second wait(0.5) end end) while true do print("Loop b", tick()) --> prints every second wait(1) end -- notice how although both loops never halt, they run simultaneously thanks to spawn
A task scheduler is essentially a large loop that goes through all of the processes it has to do and executes them. It runs as fast as it possibly can, and in Lua this is a number pretty close to 0.03.
What spawn
does is wait for the current task scheduler update to end. Then, it puts in your request to make a new thread with some code content in it into the task scheduler and will wait until the next task scheduler update. When that update happens, the thread will execute and your code will begin executing. The content of the thread itself is the function you supply to spawn
.
spawn(function() -- this is the thread that will run simultaneously with the rest of the tasks on the task scheduler end)
Threads created by spawn
are different from coroutine threads. When you create a coroutine, you create a thread but you also get a reference to the thread's associated coroutine that you can manipulate with coroutine functions.
local c = coroutine.create(function() -- new thread, coroutine.create should return a reference with type thread end) local s = spawn(function() -- new thread, spawn should return no reference end) print(type(c), type(s)) --> thread nil
spawn
does not return such a reference. It's a much more light-weight, RBX.Lua native function construct that simply queues up a new thread to the task scheduler. Once you create it, you cannot get a reference to it and you simply wait until it runs to completion.
Coroutines also run immediately and attempt to create a new thread without waiting for the current task scheduler update to complete. If you are in an environment where small increments of time like 0.03 really matter, you may want to look into coroutines over spawn.
Also note that you cannot directly pass arguments to a thread using spawn
. Calling a function within the thread with arguments is a good workaround for this.
local a = 1 local b = 2 spawn(function() print(a, b) --> 1, 2 end)