Skip to main content

Golang Concurrency #3 - Channels

Published 3 min readMarkdown
Golang Concurrency #3 - Channels

Basic Channels

Channels are Go's way for goroutines to communicate with each other. Think of them as pipes that connect goroutines.

Creating channels

ch := make(chan int)        // Channel that carries integers
ch := make(chan string)     // Channel that carries strings

Sending and receiving

ch <- 42        // Send 42 into the channel
value := <-ch   // Receive from the channel

Basic example

func main() {
    ch := make(chan string)

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

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

Key insight

Channels are synchronous by default. When you send, the sender waits until someone receives. When you receive, the receiver waits until someone sends.

This blocks forever

ch := make(chan int)
ch <- 42  // No one is receiving, so this blocks forever

This also blocks forever

ch := make(chan int)
value := <-ch  // No one is sending, so this blocks forever

Channels solve the goroutine communication problem

func main() {
    result := make(chan int)

    go func() {
        // Do some work
        answer := 42
        result <- answer  // Send result back
    }()

    fmt.Println(<-result)  // Wait for and print result
}

Go's motto

"Don't communicate by sharing memory; share memory by communicating."

Channels are the "communicating" part - they let goroutines pass data safely without shared variables.

Channel Syntax Breakdown

Creating

ch := make(chan int)
  • make() creates the channel

  • chan is the keyword for channel

  • int is the type of data this channel carries

Sending (left arrow points INTO channel)

ch <- 42
  • ch is the channel

  • <- is the send operator

  • 42 is the value going into the channel

  • Read it as: "send 42 into ch"

Receiving (left arrow points OUT OF channel)

value := <-ch
  • <-ch means "receive from ch"

  • The arrow points away from the channel

  • value gets whatever comes out

Memory trick

The arrow shows direction of data flow.


Go's Motto Explained

"Don't communicate by sharing memory; share memory by communicating."

Traditional way (sharing memory)

var counter int  // Shared variable
var mutex sync.Mutex

// Goroutine 1
mutex.Lock()
counter++
mutex.Unlock()

// Goroutine 2
mutex.Lock()
counter++
mutex.Unlock()

Both goroutines access the same counter variable. They "communicate" by both touching the same memory location.

Go's way (communicating)

ch := make(chan int)

// Goroutine 1
ch <- 1  // Send "increment by 1"

// Goroutine 2
ch <- 1  // Send "increment by 1"

// Counter goroutine
counter := 0
counter += <-ch  // Receive increment
counter += <-ch  // Receive increment

Instead of sharing the counter variable, goroutines send messages through channels.

The difference

  • Sharing memory = multiple goroutines touching the same variable

  • Communicating = goroutines sending data through channels

Channels eliminate the need for locks and make concurrent code safer.

About the author

  • Just a guy who loves to write code and watch anime.

No comments yet. Be the first to comment.