我正在尝试了解goroutine。在下面的示例中,为什么1)-4)表现不同?参见https://play.golang.org/p/_XXZe47W53v
package main
import (
"fmt"
"time"
)
func send(x int, ch chan int) {ch<-x}
func read(ch chan int) {fmt.Println(<-ch)}
func main() {
ch := make(chan int)
go read(ch) // 1) works
go send(1,ch) // -> 1
// go fmt.Println(<-ch) // 2) fatal error: all goroutines are asleep - deadlock!
// go send(1,ch) // isn't this the same as the above ?
// go send(1,ch) // 3) works
// go fmt.Println(<-ch) // -> 1
// go fmt.Println(<-ch) // 4) fatal error: all goroutines are asleep - deadlock!
// go send(1,ch) // why does the order of the go routine calls matter?
time.Sleep(100*time.Millisecond)
}
Run Code Online (Sandbox Code Playgroud)
您正在看到错误,因为读取不是在goroutine内部进行的,而是在主线程中进行的。
该行:
go fmt.Println(<-ch)
Run Code Online (Sandbox Code Playgroud)
正在评估主线程中的参数,一旦成功,它将Println使用已解析的参数在goroutine中运行。由于ch在这种状态下代码永远无法写入,因此它会死锁。
您可以将其更改为:
go func() { fmt.Println(<-ch) }()
Run Code Online (Sandbox Code Playgroud)
然后它将在周围创建一个闭包ch,然后匿名例程(而不是主线程)将被阻止,该例程可以继续到send()。
| 归档时间: |
|
| 查看次数: |
47 次 |
| 最近记录: |