Go Channel - Deadlock
- See more:
What happens when you try to send data to a full channel or receive data from an empty channel?
When you try to send data to a full channel or receive data from an empty channel, the operation will block until the channel has the available capacity or until there is data to be received. 1
If a channel is full and you try to send data to it, the sending operation will block until there is available capacity in the channel. This means that the sending goroutine will wait until a receiver removes an element from the channel to make space for the new element. 1
For example, consider a buffered channel that can hold up to 2 integers:
package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3 // this will block until space is available in the channel
fmt.Println("vim-go")
}
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/Users/me/workstation/golang/2023a04m16d-go-doc/main.go:9 +0x5c
exit status 2
Similarly, if a channel is empty and you try to receive data from it, the receiving operation will block until there is data to be received. This means that the receiving goroutine will wait until a sender sends data on the channel.
For example, consider a channel that is not buffered and can hold only one integer:
package main
import "fmt"
func main() {
ch := make(chan int)
value := <-ch // this will block until a value is sent on the channel
fmt.Println(value)
fmt.Println("vim-go")
}
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
/Users/me/workstation/golang/2023a04m16d-go-doc/main.go:7 +0x39
exit status 2
In this example, the receiving operation will block because there is no data to be received on the channel. The receiving goroutine will wait until a sender sends data on the channel.
Channels Types?
Buffered channels: This type of channel has a fixed capacity to hold a certain number of values.
package main
import "fmt"
func main() {
ch := make(chan int, 1)
ch <- 10
fmt.Println("Value sent")
fmt.Println("Receiving value")
fmt.Println(<-ch)
fmt.Println("Value received")
}
Value sent
Receiving value
10
Value received
Unbuffered channels: An unbuffered channel has no capacity to hold any values. When a value is sent on an unbuffered channel, the sender will block it until the value is received by a receiver.
package main
import "fmt"
func main() {
ch := make(chan int)
go func() {
fmt.Println("Sending value")
ch <- 10
fmt.Println("Value sent")
}()
fmt.Println("Receiving value")
fmt.Println(<-ch)
fmt.Println("Value received")
}
Receiving value
Sending value
Value sent
10
Value received