A goroutine runs a function concurrently with the function that starts it. Put `go` before a function call; the caller continues immediately rather than waiting for the call to finish. Goroutines are lightweight execution contexts managed by the Go runtime, which maps them onto operating-system threads. section 1.2.3 section 5.2
Run an echo task in the background
This complete program copies standard input to standard output while `main` keeps a 30-second timer: ```go package main import ( "fmt" "io" "os" "time" ) func main() { fmt.Println("Type anything for up to 30 seconds") go io.Copy(os.Stdout, os.Stdin) time.Sleep(30 * time.Second) fmt.Println("Timed out.") } ``` The `go` call lets the input task run while `main` waits. The sleep is only a timer, not a general way to wait for work to finish. When `main` exits, the program ends even if its goroutine is still working. section 5.2
When results must be complete before continuing, use `sync.WaitGroup`. For independent file-compression jobs, call `Add(1)` before starting each goroutine, call `Done()` when its job finishes, then call `Wait()` before printing the summary. Unlike a sleep, this waits for the specified work. section 5.2.1
Listing 5.3 Compressing files in parallel with a wait group
package main
import (
"compress/gzip"
"fmt"
"io"
"os"
"sync"
)
func main() {
var wg sync.WaitGroup #1
for i, file := range os.Args[1:] {
wg.Add(1) #2
go func(filename string) { #3
compress(filename) #3
wg.Done() #3
}(file) #4
}
wg.Wait() #5
fmt.Printf("Compressed %d files\n", len(os.Args[1:]))
}
func compress(filename string) error {
// Unchanged from above
}
The file-compression listing shows where each job starts, how its filename is passed in, and where the summary waits for all jobs. section 5.2.1
Keep concurrent work coordinated and able to finish:
- Use channels to pass values between goroutines. A channel operation blocks by default, so communication can also synchronize them. section 1.2.3
- Give long-running senders a way to stop. An abandoned receiver or open channel can leave a goroutine consuming resources; closing a channel while another goroutine sends to it causes a panic. section 5.3.2
- Handle a goroutine's panic within that goroutine when recovery is needed. A deferred recovery in a connection handler can log the failure and close the connection. section 4.3.5
A common server pattern starts a goroutine for each accepted connection so one handler does not hold up the listener. Goroutines also make it possible to monitor shutdown conditions while a server is doing other work. These are practical concurrency patterns; detailed scheduler internals are not needed to use them. section 4.3.5 section 2.3.2






