G

Concurrency (Goroutines & Channels)

Go syntax guide

Handling concurrent operations with goroutines and channels

Concurrency (Goroutines & Channels)

Handling concurrent operations with goroutines and channels

Go concurrency (goroutines & channels) (go)
        
          package main

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

// Function to run as goroutine
func printNumbers(id int) {
    for i := 0; i < 5; i++ {
        fmt.Printf("Goroutine %d: %d\n", id, i)
        time.Sleep(100 * time.Millisecond)
    }
}

// Function that returns a channel
func count(to int) <-chan int {
    ch := make(chan int)
    go func() {
        for i := 1; i <= to; i++ {
            ch <- i
            time.Sleep(500 * time.Millisecond)
        }
        close(ch)
    }()
    return ch
}

// Producer-consumer pattern
func producer(ch chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 5; i++ {
        ch <- i
        fmt.Println("Produced:", i)
        time.Sleep(100 * time.Millisecond)
    }
    close(ch)
}

func consumer(ch <-chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    for value := range ch {
        fmt.Println("Consumed:", value)
        time.Sleep(150 * time.Millisecond)
    }
}

// Select statement for channel operations
func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("Quit signal received")
            return
        }
    }
}

func main() {
    // Basic goroutines
    fmt.Println("Starting goroutines...")
    go printNumbers(1)
    go printNumbers(2)

    time.Sleep(1 * time.Second) // Wait for goroutines to finish

    // Channel basics
    fmt.Println("\nChannel operations:")
    ch := make(chan string)

    go func() {
        ch <- "Hello from goroutine!"
    }()

    message := <-ch
    fmt.Println(message)

    // Buffered channel
    bufferedCh := make(chan int, 3)
    bufferedCh <- 1
    bufferedCh <- 2
    bufferedCh <- 3

    fmt.Printf("Buffered channel length: %d, capacity: %d\n",
        len(bufferedCh), cap(bufferedCh))

    // Range over channel
    fmt.Println("\nCounting with channel:")
    for num := range count(5) {
        fmt.Println("Received:", num)
    }

    // Producer-consumer with WaitGroup
    fmt.Println("\nProducer-Consumer pattern:")
    var wg sync.WaitGroup
    prodCh := make(chan int, 5)

    wg.Add(2)
    go producer(prodCh, &wg)
    go consumer(prodCh, &wg)
    wg.Wait()

    // Select statement
    fmt.Println("\nFibonacci with select:")
    fibCh := make(chan int)
    quit := make(chan int)

    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-fibCh)
        }
        quit <- 0
    }()

    fibonacci(fibCh, quit)
}
        
      

Explanation

Go concurrency model is based on goroutines (lightweight threads) and channels (for communication between goroutines). This allows for efficient parallel execution.

Common Use Cases

  • Parallelizing computations
  • Building responsive user interfaces
  • Developing high-performance servers
  • Handling background tasks

Related Go Syntax

Master Concurrency (Goroutines & Channels) in Go

Understanding concurrency (goroutines & channels) is fundamental to writing clean and efficient Go code. This comprehensive guide provides you with practical examples and detailed explanations to help you master this important concept.

Whether you're a beginner learning the basics or an experienced developer looking to refresh your knowledge, our examples cover real-world scenarios and best practices for using concurrency (goroutines & channels) effectively in your Go projects.

Key Takeaways

  • Parallelizing computations
  • Building responsive user interfaces
  • Developing high-performance servers