How to Start a Goroutine in Go

Start a goroutine by prefixing a function call with the `go` keyword, which runs that function concurrently in a new lightweight thread managed by the Go runtime.

Start a goroutine by prefixing a function call with the go keyword, which runs that function concurrently in a new lightweight thread managed by the Go runtime. You must ensure the main function waits for these goroutines to finish, typically using sync.WaitGroup, otherwise the program will exit immediately and terminate the background tasks.

Here is a practical example using sync.WaitGroup to manage multiple goroutines:

package main

import (
	"fmt"
	"sync"
	"time"
)

func worker(id int, wg *sync.WaitGroup) {
	defer wg.Done() // Signal completion when the function returns
	time.Sleep(time.Second)
	fmt.Printf("Worker %d finished\n", id)
}

func main() {
	var wg sync.WaitGroup

	// Start 3 goroutines
	for i := 1; i <= 3; i++ {
		wg.Add(1) // Increment counter before starting
		go worker(i, &wg)
	}

	// Block until all goroutines call Done()
	wg.Wait()
	fmt.Println("All workers completed.")
}

If you need to pass data back from a goroutine, use channels instead of shared variables. Here is a simple pattern for collecting results:

package main

import (
	"fmt"
	"time"
)

func calculate(id int, resultChan chan int) {
	time.Sleep(time.Millisecond * 100)
	resultChan <- id * 2
}

func main() {
	ch := make(chan int, 3)

	for i := 1; i <= 3; i++ {
		go calculate(i, ch)
	}

	// Collect results
	for i := 0; i < 3; i++ {
		fmt.Println(<-ch)
	}
}

Remember that goroutines are extremely cheap to create, so spawning thousands is common, but you must always handle synchronization. If the main function returns before your goroutines finish, the entire process exits, killing them silently. Always use WaitGroup for simple coordination or channels for data exchange to ensure your concurrent logic completes as expected.