i'm new to Go not sure why this is deadlock ? i want to constantly be reading results from doSomething and storing it in the function read without using a for loop
func doSomething(c chan<- string){ // recursive function does something
c <- result
return dosomething(c) }
func reads(c <-chan string){
results := ""
temp := <-c
results = results + "\n" + temp
return results
}
func main(){
go reads(c)
doSomething(c)
}
Main gorouting is trying to write multiple times to a channel in doSomething
function. The read
function is reading the channel only once. Therefore the write operation will wait until some other party reads from the channel. This will deadlock as the main goroutine is blocked.
If the blocking operations were not in main goroutine, the program would finish as the Go program ends whenever main goroutine ends. There would be no deadlock if main function could come to an end.
You are trying to read from an empty channel because reads
executed concurrently and doSomething
didn't. It is possible to solve the problem in several ways. Note, it is not about correct architecture or efficient approaches. An examples below solve "deadlock" issue of the original snippet, not more.
Read and write concurrently:
package main
func doSomething(c chan<- string) { // recursive function does something
c <- "result"
doSomething(c)
}
func reads(c <-chan string) {
results := <-c
fmt.Println("Boo", results)
}
func main() {
c := make(chan string)
go reads(c)
go doSomething(c) // Write concurrentely
}
Use select
to handle channels read operation:
func reads(c <-chan string) {
// Use select
select {
case res := <-c:
fmt.Println("received message", res)
default:
fmt.Println("no results received")
}
}
I'd rather prefer combination of the first and second approaches.
Read after write (it is far from correct design as hell):
func main() {
c := make(chan string)
go doSomething(c)
reads(c) // Read after write
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.