Multiple execution paths in a process

A multithreaded process maintains several execution positions, each with its own register and call state. Threads typically share code, global data, and the heap. This lets one thread access information created by another without always passing through an external communication interface, while retaining separate execution histories within the same process.

References: [1]

Coordinating shared data

Two threads updating one counter can interleave their reads and writes and lose an update. Locks, atomic operations, and other synchronization mechanisms constrain access to shared state. Their scope should reflect the actual sharing pattern: broad locking limits concurrency, while overly fragmented locking adds coordination cost and makes correctness harder to reason about.

References: [2]

Who schedules the work

Operating systems may schedule threads directly, while language runtimes can map their own activities onto system threads. Multiple cores permit parallelism, subject to scheduling and program conditions. Coroutines describe suspension and resumption mechanisms, so a runtime can combine them with threads without requiring one coroutine to correspond to exactly one system thread.

References: [1]

Creation and completion

Thread interfaces define entry functions, arguments, stack attributes, and completion behavior. Waiting for termination differs from repeatedly polling while consuming processor time. Long-lived services also need bounded thread counts and failure propagation, ensuring that completed or failed activities do not indefinitely retain resources or leave dependent work waiting without a completion path.

References: [2]