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
- Is used by: Fork-join, Structured concurrency
- See also: Daemon and detached threads, Future and promise
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¶
- In this library: Who waits when main returns?
- In this library: Getting a result back
- In a sibling library: Rust: Spawning a thread ↗
- In a sibling library: Go: A goroutine has no handle ↗
- In a sibling library: Go:
maindoes not wait ↗ - In a sibling library: Go: A WaitGroup counts goroutines ↗
- In the books: Learn Concurrent Programming with Go, James Cutajar — ch. 6, 'Synchronizing with waitgroups and barriers'
- In the books: Async Rust, Maxwell Flitton, Caroline Morton — ch. 3, 'Building Our Own Async Queues' → 'Creating Our Own Join Macro'
- In the books: Concurrency with Modern C++, Rainer Grimm — ch. 6, 'The Future: C++20/23' → 'A Cooperatively Interruptible Joining Thread'
- In the books: Pro Asynchronous Programming with .NET, Richard Blewett, Andrew Clymer — ch. 4, 'Basic Thread Safety' → 'CountdownEvent: Simplifying Fork and Join'
- In the books: Effective Concurrency in Go, Burak Serdar — ch. 2, 'Go Concurrency Primitives' → 'Wait groups'
- In the books: The Linux Programming Interface, Michael Kerrisk — ch. 29, 'Threads: Introduction' → 'Joining with a Terminated Thread'