Buffered Channel in Golang

Channels can be defined as a pipes using which Goroutines communicate. Similar to water flows from one end to another in a pipe, data can be sent from one end and received from the another end using channels. By default channels are unbuffered, which states that they will only accept sends (chan <-) if there is a corresponding receive (<- chan) which are ready to receive the sent value. Buffered channels allows to accept a limited number of values without a corresponding receiver for those values. It is possible to create a channel with a buffe. Buffered channel are blocked only when the buffer is full. Similarly receiveing from a buffered channel are blocked only when the buffer will be empty.

Buffered channels can be created by passing an additional capacity parameter to the make( ) function which specifies the size of the buffer.

Syntax :

ch := make(chan type, capacity)           // chan defines channel type 

Here , capacity in the above syntax should be greater than 0 for a channel to have a buffer. The capacity for an unbuffered channel is 0 by default and hence it omit the capacity parameter.



Example 1 : Code to create a buffered channel.

Go

filter_none

edit
close

play_arrow

link
brightness_4
code

package main
  
import (
    "fmt"
)
  
func main() {
  
    // create a buffered channel 
    // with a capacity of 2.
    ch := make(chan string, 2)
    ch <- "geeksforgeeks"
    ch <- "geeksforgeeks world"
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

chevron_right


Output:

geeksforgeeks
geeksforgeeks world

Here in above code ,it is possible to write 2 strings into the channel without being blocked. It take 2 strings to the channel  and does not block and print the result.

Example 2 :  Program that write to buffered channel block.

Go

filter_none

edit
close

play_arrow

link
brightness_4
code

package main
  
import (
    "fmt"
    "time"
)
  
func write(ch chan int) {
    for i := 0; i < 4; i++ {
        ch <- i
        fmt.Println("successfully wrote", i, "to ch")
    }
    close(ch)
}
func main() {
  
    // creates capacity of 2
    ch := make(chan int, 2)
    go write(ch)
    time.Sleep(2 * time.Second)
    for v := range ch {
        fmt.Println("read value", v, "from ch")
        time.Sleep(2 * time.Second)
  
    }
}

chevron_right


Output: 

successfully wrote 0 to ch
successfully wrote 1 to ch
read value 0 from ch
successfully wrote 2 to ch
read value 1 from ch
successfully wrote 3 to ch
read value 2 from ch
read value 3 from ch

Here in above code the write Goroutine has a for loop which writes numbers from 0 to 3 to the ch channel. The capacity of this buffered channel is 2 and hence the write Goroutine will be able to write values 0 and 1 to the ch channel immediately and then it blocks until at least one value is read from ch channel as defined below :-

successfully wrote 0 to ch
successfully wrote 1 to ch

After that, the read value and then sleeps for 2 seconds again and this cycle continues until the ch is closed. So the program will print the following lines after 2 seconds, as :-

read value 0 from ch  
successfully wrote 2 to ch 

And this will continue until all values are written to the channel and it is closed in the write Goroutine.

Deadlocks in Buffered Golang Channel

It is defined as situation where the program during execution  will result in fatal error due to panic at run time.

Example :

Go

filter_none

edit
close

play_arrow

link
brightness_4
code

package main
  
import (
    "fmt"
)
  
func main() {
    ch := make(chan string, 2)
    ch <- "geeksforgeeks"
    ch <- "hello"
    ch <- "geeks"
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

chevron_right


Here , in above code the write is blocked since the channel has exceeded its capacity and program reaches deadlock situation and print following message :

fatal error: all goroutines are asleep - deadlock!



goroutine 1 [chan send]:

main.main()

    /tmp/sandbox048494311/prog.go:11 +0x8d



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.