Hi,
while trying out something involving multithreading, I came across an issue I just can't explain.
I'm setting up a thread like this:
var thread
func _ready():
thread = Thread.new()
thread.start(self, "thread_process")
func thread_process():
while true:
if stuff_to_do: #I know there should be a mutex here, but this is just set to true by a button for testing once
do_stuff()
func do_stuff():
if thread.is_active():
print("thread is active")
else:
print("Thread is not active")
print("1")
do_more_stuff() #those do some stuff that takes a few frames
print("2")
do_more_stuff()
print("3")
do_even_even_more_stuff()
print("4")
do_even_even_even_more_stuff()
if thread.is_active():
call_deferred("end_thread")
func end_thread():
thread.wait_to_finish()
Now, I know joining the thread like this while thread_process() is stuck in the infinite loop doesn't make sense, it's about understanding the behavior. Because what happens, is that it does not print "thread is active 1 2 3 4" as expected, but usually only "thread is active 1 2 3", sometimes only "thread is active 1 2". So do_stuff never finished. However, and here is something I understand even less, if I change thread_process() like so:
func thread_process():
while true:
if stuff_to_do:
do_stuff()
else:
yield(get_tree(), "idle_frame")
it actually prints 1-2-3-4 as expected. But then something else weird happens, if I set stuff_to_do = true again, do_stuff() will run again, and print "thread is not active 1 2 3 4". How does that even works, the thread should not even be active anymore? Or does the fact, that thread_process() is still running that loop prevents it from joining? But why would .is_active() return false then? And in the first place, why does do_stuff() not finish without the yield(get_tree(), "idle_frame")? This is something I'd really like to understand but after sitting here for a whole day and experimenting I don't know what to try else... The debugger not working with threads is a real bummer.