Buffered Channel in Golang - GeeksforGeeks

21 Dec, 2021
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 receiving 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
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)}
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
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)      }}
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.
It is defined as situation where the program during execution  will result in fatal error due to panic at run time.
Example :
Go
package main  import (    "fmt")  func main() {    ch := make(chan string, 2)    ch <- "geeksforgeeks"    ch <- "hello"    ch <- "geeks"    fmt.Println(<-ch)    fmt.Println(<-ch)}
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

varshagumber28
Golang-Concurrency
Go Language
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Arrays in Go
How to Split a String in Golang?
fmt.Sprintf() Function in Golang With Examples
Slices in Golang
Golang Maps
Interfaces in Golang
Inheritance in GoLang
Different Ways to Find the Type of Variable in Golang
How to Trim a String in Golang?
How to compare times in Golang?