What is the difference between goroutines and threads

Goroutines are lightweight, runtime-managed concurrent units, while threads are heavier, kernel-managed execution units that goroutines multiplex onto.

Goroutines are lightweight, user-space threads managed by the Go runtime, while threads are heavier, kernel-managed execution units. Goroutines are multiplexed onto a smaller pool of OS threads, allowing thousands to run concurrently with minimal overhead, whereas creating thousands of OS threads often exhausts system resources. Use goroutines for concurrent tasks in Go; use OS threads (via runtime.LockOSThread) only when you must pin a goroutine to a specific thread for C interoperability or strict timing requirements.

// Goroutine: lightweight, managed by Go runtime
func worker(id int) {
    fmt.Println("Worker", id)
}

for i := 0; i < 1000; i++ {
    go worker(i) // Spawns 1000 goroutines efficiently
}

// OS Thread: heavy, pinned via runtime.LockOSThread
func pinnedWorker(id int) {
    runtime.LockOSThread() // Forces this goroutine to run on a dedicated OS thread
    defer runtime.UnlockOSThread()
    fmt.Println("Pinned Worker", id)
}

for i := 0; i < 1000; i++ {
    go pinnedWorker(i) // Spawns 1000 OS threads (expensive)
}