I need to spawn a thread to do some long process which will show progress on the main thread GUI and after the process is completed I need to continue to do other task using the results from the thread process.
Following is the code I am using now and I am not sure if it's a proper way.

func _ready():
  myThread = Thread.new()
  myThread.start(self, "longProcess")

func processDone():
  myThread.wait_to_finish()
  # continue other task using processing results from myThread

func longProcess():
  # do some long processing task
  self.call_deferred("processDone")

So, you can't really have threads join themselves (in any language). It's kind of complicated to sync them and a thread joining itself will almost always fail or lead to strange bugs. The better way is for the main thread to handle this. In C++ you can use atomics (like a bool that is synced between all threads). The atomic can be set in a thread, and you are guaranteed all reads and writes are correct. This could be a boolean, like job_is_done, or it could be an atomic counter, jobs_done, and then you can trigger the completion when all jobs are done. Or you can have the thread complete on it's own (for example if it loops a certain number of times and finishes) then it should automatically sync with the main thread if you join them at some point in the future. If the process does not have a clear end, then you can have the main thread check a variable (ideally an atomic, but you might be able to get around it depending on how many threads you have) and then the main thread will join the child threads. But in your case I don't think your method is the worst. The only issue is if calls to the main thread are not safe, you may not be able to guarantee the order or avoid interlacing. It's hard to say for sure without doing more research.

    cybereality The entire code is within a scene of Node2D and self.call_deferred("processDone") that self is referring to Node2D's instance.
    Seems to work well I have run it many times and there was no error but I'm not sure if this is a proper way or standard practise. In processDone() I have myThread.wait_to_finish() which I also not sure if it's needed at all...

    Right. What I'm talking about is more applicable if you have a distributed task (like 10 threads splitting up the work). In your case, if only one other thread is calling that function it should be okay.