More Code Examples on Deadlock in Go
Deadlock Using for…range
Closing the channel is necessary to inform the receiver that no more values are to be received and that the loop should be terminated.
In a for..range
loop utilizing a channel, it's crucial to explicitly close the channel once all values have been sent. If the channel is not closed, the for..range
loop will persistently wait for additional values from the channel. If the channel stops receiving values without being closed, the for..range
loop remains in a perpetual state of waiting, causing the goroutine or function containing the loop to become stuck. In such circumstances, no other function or goroutine can advance, resulting in a deadlock.
Code
Create a deadlock-using-for-range.go
in your current directory.
package main
import "fmt"
func DeadlockUsingForRange() {
channel := make(chan int)
go func() {
for i := 0; i < 100; i++ {
channel <- i
}
}()
for val := range channel {
fmt.Printf("%d", val)
}
}
Now, in your main.go
file, call DeadlockUsingForRange()
method.
package main
func main() {
DeadlockUsingForRange()
}
Now run go run .
to see the output.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.DeadlockUsingForRange()
/Users/aakashverma/Documents/Learning/Go/go-concurrency/deadlock/deadlock.go:14 +0xd4
main.main()
/Users/aakashverma/Documents/Learning/Go/go-concurrency/deadlock/main.go:4 +0x1c
exit status 2
Deadlock Using select
The select
function randomly selects one of the case statements to execute from all the available statements
that have data to process. If no case statement is ready to process, the default statement will be executed.
Let's look at the below code.
Code
Create a deadlock-using-select.go
in your current directory.
package main
func DeadlockUsingSelect() {
channel := make(chan int)
select {
case <-channel:
}
}
Now, in your main.go
file, call DeadlockUsingSelect()
method.
package main
func main() {
DeadlockUsingForRange()
}
Now run go run .
to see the output.
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.DeadlockUsingSelect(...)
/Users/aakashverma/Documents/Learning/Go/go-concurrency/deadlock/deadlock.go:6
main.main()
/Users/aakashverma/Documents/Learning/Go/go-concurrency/deadlock/main.go:4 +0x30
exit status 2
This code will throw a deadlock error because no case statement is ready to execute, and there’s no default statement.
The select
function will wait forever, and since there are no other Goroutines,
the code will throw a deadlock error.