英文:
not sure why this is deadlock in golang?
问题
我是你的中文翻译助手,以下是翻译好的内容:
我对Go语言还不熟悉,不确定为什么会出现死锁的情况?我想要不使用for循环,不断地从doSomething函数中读取结果并将其存储在read函数中。
func doSomething(c chan<- string) { // 递归函数做一些事情
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)
}
请注意,这是你提供的代码,我只是将其翻译成了中文。
英文:
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)
}
答案1
得分: 1
主要的goroutine在doSomething
函数中尝试多次向一个通道写入数据。read
函数只读取一次通道。因此,写操作将等待直到其他方从通道中读取数据。由于主要的goroutine被阻塞,这将导致死锁。
如果阻塞操作不在主要的goroutine中,那么当主要的goroutine结束时,程序将结束。如果主函数能够结束,就不会发生死锁。
英文:
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.
答案2
得分: 1
你正在尝试从一个空通道中读取数据,因为reads
和doSomething
函数是并发执行的。有几种方法可以解决这个问题。请注意,这并不涉及正确的架构或高效的方法。下面的示例解决了原始代码片段中的"死锁"问题,没有更多的内容。
并发读写:
package main
func doSomething(c chan<- string) { // 递归函数做一些事情
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) // 并发写入
}
使用select
处理通道的读操作:
func reads(c <-chan string) {
// 使用select
select {
case res := <-c:
fmt.Println("received message", res)
default:
fmt.Println("no results received")
}
}
*我更喜欢第一种和第二种方法的结合。*
**写后读(这远非正确的设计):**
```go
func main() {
c := make(chan string)
go doSomething(c)
reads(c) // 写后读
}
英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论