Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Impara Goroutines: Lightweight Threads | Introduction to Concurrency in Go
Practice
Projects
Quizzes & Challenges
Quiz
Challenges
/
Concurrency in Go

bookGoroutines: Lightweight Threads

Scorri per mostrare il menu

Introduction

Go is designed with concurrency in mind, making it easy for you to write programs that handle multiple tasks at the same time. Concurrency allows your applications to perform several operations independently, such as processing web requests, reading files, or handling user input, all without waiting for one task to finish before starting another.

In Go, concurrency is managed using goroutines. A goroutine is a lightweight thread managed by the Go runtime. You can start thousands of goroutines in a single program without overwhelming your system’s resources. This makes Go a popular choice for building scalable, efficient, and responsive software.

Understanding how goroutines work is the first step to unlocking Go’s powerful concurrency features. In this chapter, you will learn what goroutines are, how to create them, and why they are essential for writing concurrent programs in Go.

What Are Goroutines?

Goroutines are functions or methods that run concurrently with other functions in Go. When you launch a goroutine, you create a lightweight thread managed by the Go runtime, not the operating system. This means you can run thousands of goroutines at the same time without high memory or performance costs.

A goroutine starts with the go keyword followed by a function call. It runs independently, so your program can continue executing other code while the goroutine works in the background.

Key points about goroutines:

  • Goroutines are much lighter than traditional threads;
  • The Go runtime handles their scheduling and execution;
  • You use the go keyword to start a new goroutine;
  • Goroutines make it easy to perform multiple tasks at the same time, like handling web requests or processing data.

Example:

// This function will print a message
func printMessage() {
    fmt.Println("Hello from a goroutine!")
}

func main() {
    go printMessage() // Starts printMessage as a goroutine
    fmt.Println("Main function running")
    time.Sleep(time.Second) // Wait for goroutine to finish
}

In this example, printMessage runs as a goroutine, while the main function continues. Both messages may print in any order, showing that the functions run concurrently.

Why Goroutines Are Called Lightweight Threads

Goroutines are often described as lightweight threads because they use far fewer resources than traditional operating system threads. Here’s what makes them lightweight:

  • Goroutines start with a very small stack size, typically around 2 KB;
  • The stack size of a goroutine grows and shrinks automatically as needed, so you can launch thousands of goroutines without running out of memory;
  • Goroutines are managed by the Go runtime, not the operating system, which avoids the overhead of creating and switching OS threads;
  • The Go scheduler handles goroutine execution efficiently, allowing many goroutines to run on a limited number of OS threads;
  • Communication between goroutines is simple and safe using Go’s channels.

Because of these features, you can use thousands or even millions of goroutines in a single Go program. This makes concurrent programming in Go both practical and efficient, even on machines with modest resources.

Goroutines vs. Traditional Threads

Understanding how goroutines differ from traditional operating system threads is key to appreciating Go's approach to concurrency. Here are the main differences you need to know:

Resource Consumption

  • Goroutines use a much smaller initial stack (typically around 2KB) compared to threads, which often require 1MB or more;
  • The stack size of a goroutine grows and shrinks automatically as needed, while thread stacks are fixed at creation;
  • You can create thousands or even millions of goroutines in a single program without exhausting system resources, while creating the same number of threads would quickly overwhelm most systems.

Creation Overhead

  • Goroutines are created with a simple function call using the go keyword, with almost no setup time or system calls involved;
  • Creating a traditional thread usually involves a significant performance cost due to interaction with the operating system kernel and allocation of a large stack;
  • Goroutines start faster and use less memory, enabling highly concurrent applications with minimal overhead.

Scheduling

  • Goroutines are scheduled by Go's own runtime scheduler, not the operating system;
  • The Go scheduler multiplexes thousands of goroutines onto a smaller number of operating system threads, balancing them efficiently;
  • Traditional threads rely on the operating system's scheduler, which is less efficient for large numbers of lightweight tasks.

These differences make goroutines a powerful tool for building scalable, concurrent applications in Go. You can launch many concurrent tasks with minimal cost, letting you focus on your program's logic rather than low-level thread management.

main.go

main.go

copy
12345678910111213141516
package main import ( "fmt" "time" ) func main() { go func() { fmt.Println("Hello from the goroutine!") }() // Wait briefly to allow the goroutine to finish time.Sleep(100 * time.Millisecond) fmt.Println("Main function complete.") }

Step-by-step explanation: launching a goroutine

  1. You define a function named printMessage that prints a message to the console;
  2. In the main function, you start by launching printMessage as a goroutine using the go keyword. This tells Go to run printMessage concurrently with the rest of your code;
  3. After launching the goroutine, the main function uses time.Sleep to pause for a short period. This gives the goroutine enough time to run before the program exits;
  4. Without the time.Sleep, the main function might finish and exit before the goroutine runs, causing the program to end before the message is printed.

This approach demonstrates how goroutines allow you to run functions concurrently, but also highlights that you need to ensure your program stays alive long enough for goroutines to complete their work.

question mark

Which statement best describes a key characteristic of goroutines in Go

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 1. Capitolo 3

Chieda ad AI

expand

Chieda ad AI

ChatGPT

Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione

Sezione 1. Capitolo 3
some-alt