Do I really need to defer when calling join on a thread?

I am currently working through ziglings, and on the exercise on threads, I noticed defer was used while calling join on thread. See exercises/exercises/104_threading.zig at main - ziglings/exercises -

// Waits for the thread to complete,
// then deallocates any resources created on `spawn()`.
defer handle.join();

My reading of defer is that it runs at the time a scope is being dropped, and hence there is a pattern of having de-allocating code to run at that point…but in this case, an handle is being joined on, what part of that means memory would be de-allocated as mentioned in the comment?

I thing I noticed, is that if I remove the defer then the tasks are executed in order. Which makes sense because join means the threads wait on each other before the next executes. This I understand and this I would expect to be the reason to have defer and not because of de-allocating memory.

So is the comment misleading in the exercise? or am I getting something wrong?

I don’t think it’s misleading because, although not always, there could be implementations of spawn that use an allocator to allocate the memory needed by the new thread. In such a case, that allocation would be freed on join, so the defer is performing double-duty by waiting for the thread to finish and possibly freeing any allocated memory.

1 Like

Maybe something to clarify too is the defer keyword doesn’t have to be related to freeing memory, it just ends up being used for that a majority of the time since it’s the best tool for the job.

defer std.debug.print("Called at end of scope!", .{});

Would be a perfectly valid use of defer.


From std.Thread.spawn documentation:

Spawns a new thread which executes function
The caller must eventually either call join() to wait for the thread to finish and free its resources or call detach() to excuse the caller from calling join() and have the thread clean up its resources on completion.

join function deallocates the resources created by spawn.
defer simply postpones the execution.