Can someone please explain threads as it pertains to spawn() and coroutines and how they interact with existing threads?
(Sidenote: SH mods, would it be possible to consider increasing the char count on questions to 150 or even 200? I think the above question is completely reasonable in terms of length.)
I tend to use spawn() and coroutines quite commonly when working with different areas of code. I know they do what I need them to do, however, I'm not sure they are efficient, when and when not to use them, or how to explain them.
This is a question I'm asked frequently and have never been fully satisfied with the answer I'm able to provide.
To understand how to take everything out of threads, you have to understand what the Roblox task scheduler is -- the underlying system that's managing which thread to run and when. Keep in mind it's not multithreading in the sense of running code in different computer cores.
None of your script instances are run at the exact same time as they are executed singlethreaded; by one computer core. However, the task scheduler allows them to run right after one another, appearing like they are running in parallel.
As the machine clock updates, the system iterates through all the threads found between the last update timestamp and the new timestamp in the order of appearance and continues their execution. You can think of the task scheduler as an ordered stack where whenever your code yields, the yielding thread is pushed to the stack, position defined by the timestamp (with the wait
function sys_time + yield_time
). The scheduler steps to the next thread immediately after the one being executed ends or yields.
Each of your script instances (not ModuleScripts as they're used by script instances) are their own thread. However, coroutines allow them to create new, completely separate threads. They still function the exact same. When you execute a coroutine, the caller thread is paused by the task scheduler until the coroutine thread yields or ends, then the caller thread is continued. If the coroutine yields, it is pushed to the corresponding position in the stack.
In simple terms, creating a new thread with coroutines is like creating a new script instance.
The spawn
function also uses coroutines. What it does is simply push the new created thread to the next step in the task scheduler -- so pretty much at timestamp sys_time + 1/60
.