Skip to content

Join

Category: Async · Status: stub · Lessons: chapter 01, Threads

One line: Waiting for a thread or task to finish, usually receiving its result or its failure through a handle.

Also called: join handle, JoinHandle, WaitGroup, await.

How it connects

flowchart LR
  n_fork_join["Fork-join"]
  n_join["Join"]
  n_structured_concurrency["Structured concurrency"]
  n_fork_join -->|uses| n_join
  n_structured_concurrency -->|uses| n_join
  classDef center stroke-width:3px
  class n_join center
  classDef outside stroke-dasharray: 4 3
  class n_fork_join,n_structured_concurrency outside

In each language

Rust JoinHandle::join returns the thread's result, or Err if the thread panicked
Go no handle to join: count goroutines with a sync.WaitGroup, which also has a Go method, or receive their results on a channel
C pthread_join suspends the caller until the target thread terminates
C++ std::thread::join; destroying a thread that is still joinable calls std::terminate (destructor ↗), which a std::jthread avoids by joining
Java Thread.join, or get on a Future
Python Thread.join
C# Thread.Join; for tasks, await or Task.WhenAll
JavaScript Promise.all, which rejects as soon as any input promise rejects
Kotlin Job.join suspends until the job is complete, for any reason
Swift await a task's value (Swift book ↗)
Erlang and Elixir Task.await
The operating system waitpid for a child process

Where to read more