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

bookGo's Approach to Concurrency

Scorri per mostrare il menu

Go provides a simple and powerful way to handle concurrency, making it accessible for beginners. Its built-in features allow you to write programs that can manage multiple tasks at the same time, without complex setup or advanced knowledge. By using Go's concurrency tools, you can build efficient and responsive applications with ease.

Go’s Concurrency Model

Go is designed with concurrency in mind. It makes concurrent programming straightforward by introducing goroutines and channels. These tools embody Go’s philosophy: simplicity and communication over shared memory.

Goroutines: Lightweight Concurrent Tasks

A goroutine is a lightweight thread managed by the Go runtime. You can start a new goroutine by prefixing a function or method call with the go keyword. Goroutines are much cheaper than traditional threads, so you can run thousands of them in a single program.

Example:

package main

import (
    "fmt"
    "time"
)

func sayHello() {
    fmt.Println("Hello from goroutine!")
}

func main() {
    go sayHello() // Start a new goroutine
    fmt.Println("Hello from main function!")
    time.Sleep(time.Second) // Wait for goroutine to finish
}

Channels: Safe Communication Between Goroutines

A channel is a typed conduit you use to send and receive values between goroutines. Channels let you build concurrent programs that communicate safely, without directly sharing memory. This approach reduces bugs caused by data races or inconsistent state.

Example:

package main

import "fmt"

func main() {
    messages := make(chan string) // Create a channel

    go func() {
        messages <- "ping" // Send value to channel
    }()

    msg := <-messages // Receive value from channel
    fmt.Println(msg)
}

Go’s Philosophy: Communication Over Shared Memory

Go encourages you to share data by communicating, not by sharing memory directly. This means:

  • You pass data between goroutines using channels;
  • You avoid complex locking or manual synchronization;
  • You write code that is easier to read, maintain, and reason about.

By following this model, you reduce the risk of subtle concurrency bugs and make your programs more robust.

main.go

main.go

copy
12345678910111213141516171819202122232425
package main import ( "fmt" "time" ) func printNumbers(ch chan string) { for i := 1; i <= 3; i++ { msg := fmt.Sprintf("Number: %d", i) ch <- msg time.Sleep(300 * time.Millisecond) } close(ch) } func main() { ch := make(chan string) go printNumbers(ch) for msg := range ch { fmt.Println(msg) } fmt.Println("Done!") }

How Goroutines and Channels Work Together

Go uses goroutines and channels to make concurrent programming simple and safe.

  • A goroutine is a lightweight thread managed by Go. You launch a goroutine by adding the go keyword before a function call;
  • Channels are typed pipes that allow goroutines to communicate and synchronize execution without explicit locks;
  • You send a value into a channel using the <- operator, and receive a value from a channel the same way;
  • Channels ensure that data is passed safely between goroutines, preventing race conditions.

Code Walkthrough

Suppose you have this code:

package main

import (
    "fmt"
    "time"
)

func printMessage(message string, ch chan string) {
    time.Sleep(1 * time.Second)
    ch <- message // Send message to channel
}

func main() {
    ch := make(chan string) // Create a channel
    go printMessage("Hello from goroutine!", ch) // Start goroutine

    msg := <-ch // Receive message from channel
    fmt.Println(msg)
}

Here’s how this code achieves concurrency:

  • You create a channel named ch using make(chan string);
  • You start a new goroutine with go printMessage(...). This runs printMessage concurrently with main;
  • The printMessage function waits for one second, then sends a string value into the channel with ch <- message;
  • Meanwhile, the main function waits to receive a value from the channel using msg := <-ch. This blocks until a value is available;
  • When the goroutine sends the message, the main function receives it and prints it.

This pattern lets multiple tasks run at the same time and coordinate safely using channels. You avoid manual locking and race conditions, making your concurrent programs easier to write and understand.

question mark

Which Go feature is used to start a lightweight concurrent function execution?

Select the correct answer

Tutto è chiaro?

Come possiamo migliorarlo?

Grazie per i tuoi commenti!

Sezione 1. Capitolo 2

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 2
some-alt