Godot Version
4.2.1
Question
Hi Everyone,
I’ve starting working on my pathfinding code for my game and I’ve been wanting to move the execution of all this code off onto another thread so the main thread doesn’t lag from the calculations being performed for this task. I was wondering what is the best way to do this.
For starters, I just made some test code that does an expensive calculation/loop to lag the main thread. Then I moved it to another thread. I found two methods online, and I was wondering which one was better, or if there is an even better way to do this?
This first method only starts the thread after it has already completed it’s previous task.
var thread : Thread
func _ready():
# create thread
thread = Thread.new()
func do_math(a, b, c):
# Do some overly complicated laggy calculation
a = 0
for i in range(0, 10000000):
a = a + i / 2000 + b + c
print(a, " :: ", b, "::", c)
func _on_timer_timeout():
# Have a timer call the thread every 1 second
# If the thread is still processing the function, return
if thread.is_alive() == false:
# If the thread it started and finished, join it
if thread.is_started():
thread.wait_to_finish()
# Once thread is finished, call thread to run function again
thread.start(do_math.bind(1,2,3))
func _exit_tree():
# On program exit, wait for the thread to finish
thread.wait_to_finish()
The second one constantly runs a while loop in the separated thread, but a semaphore tells it when to run the calculation. ( I personally don’t think this one is as good as the above since the constantly running while loop is unnecessary processing even if on a different thread.)
var a = 0
var b = 0
var c = 0
var semaphore : Semaphore
var thread : Thread
var exit_loop = false
func _ready():
thread = Thread.new()
semaphore = Semaphore.new()
thread.start(threadRun.bind(""))
func threadRun(userdata):
while true: # Thread runs forever on one of your cores
semaphore.wait() # Thread waits here on this line until receiving "semaphore.post()".
if exit_loop:
break
a = 0
for i in range(0, 10000000):
a = a + i / 2000 + b + c
self.call_deferred('math_done', a, b, c)
func math_done(a, b, c):
print(a, "::", b, "::", c)
func _on_timer_timeout():
# Have a timer call the semaphore every 1 second
if semaphore != null:
semaphore.post()
func _exit_tree():
exit_loop = true
semaphore.post()
thread.wait_to_finish()
Thanks