How to work with buffered channels?

1 6 61
calendar_todayschedule3 min read
— Originally published at dev.to

Hello, I'm Ganesh. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. Star Us to help devs discover the project. Do give it a try and share your feedback for improving the product.

In Channels We Go, there are 2 types of channels.

  1. Buffered channels
  2. Unbuffered channels

In this article, we will learn about buffered channels.

Buffered channels

Buffered channels are channels that have a buffer size.

How to create a buffered channel?

Which will be defined by the second argument to the makefunction.

This will make the channel able to hold the number of values equal to the buffer size.

package main

import "fmt"

func main() {
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

Let's add 2 values to the channel and print them.

Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
1
2

Now let's add 3 values to the channel and print them.

package main

import "fmt"

func main() {
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2
    ch <- 3
    fmt.Println(<-ch)
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
        /home/gk/exp/code/rd/go-exmaple/main.go:9 +0x58
exit status 2

In the error message, we can see that all goroutines are asleep—deadlock!

This is because we are trying to send 3 values to the channel which has a buffer size of 2.

So, the value 3 will be waiting for a receiver to receive it.

But there is no receiver to receive it.

So, the program will deadlock.

Also, we are sending 3 values in the main thread and receiving 3 values in the main thread. So, the program will deadlock.

How to avoid deadlock:

we should send values to the channel in a separate goroutine.

The receiver should be in a separate goroutine.

package main

import "fmt"

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

    // Start a concurrent routine to send the data
    go func() {
        ch <- 1
        ch <- 2
        ch <- 3
    }()

    // Main routine reads the data as it comes in
    fmt.Println(<-ch)
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
1
2
3

Loop over a channel

We can use the for range loop to iterate over a channel.

package main

import "fmt"

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

    // Start a concurrent routine to send the data
    go func() {
        ch <- 1
        ch <- 2
        ch <- 3
    }()

    // Main routine reads the data as it comes in
    for i := range ch {
        fmt.Println(i)
    }
}

Expected Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
1
2
3

Actual Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
1
2
3
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
        /home/gk/exp/code/rd/go-exmaple/main.go:16 +0xc5
exit status 2

We expected the output to be 1, 2, 3.
But we got a deadlock.

This is because the for range loop will wait for the channel to be closed.

But we didn't close the channel.

let's close the channel.

package main

import "fmt"

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

    // Start a concurrent routine to send the data
    go func() {
        ch <- 1
        ch <- 2
        ch <- 3
        close(ch)
    }()

    // Main routine reads the data as it comes in
    for i := range ch {
        fmt.Println(i)
    }
}

Output:

gk@jarvis:~/exp/code/rd/go-exmaple$ go run main.go 
1
2
3

Conclusion

We explored how to work with buffered channels.

Understood how to avoid deadlock in buffered channels.

We also understood how to loop over a channel.

Next we will see how to work with unbuffered channels.

git-lrc

Any feedback or contributors are welcome! It’s online, source-available, and ready for anyone to use.
⭐ Star it on GitHub: https://github.com/HexmosTech/git-lrc

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

How I Built a React Portfolio in 7 Days That Landed ₹1.2L in Freelance Work

Dharanidharan - Feb 9

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelski - Mar 19

What Is SARIF and How Does It Help Security Tools Work Together?

Ganesh Kumar - Jul 4

How to work with channels?

Ganesh Kumar - Apr 1

Breaking the AI Data Bottleneck: How Hammerspace's AI Data Platform Eliminates Migration Nightmares

Tom Smithverified - Mar 16
chevron_left
1.4k Points68 Badges
68Posts
6Comments
5Connections
Right now I'm focused on LiveReview, AI code review that gives teams control over AI-generated code without slowing them down.

Related Jobs

View all jobs →

Commenters (This Week)

3 comments
2 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!