为什么调用 goroutines 的顺序和方式很重要?
Why does order and way of calling goroutines matter?
我正在尝试了解 goroutines。
在下面的示例中,为什么 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)
}
您看到错误是因为读取不是发生在 goroutine 内部,而是发生在主线程中。
行:
go fmt.Println(<-ch)
正在主线程中评估参数,一旦成功,它将 运行 goroutine 中的 Println
与已经解析的参数。由于代码永远无法在此状态下写入 ch
,因此它会死锁。
您可以将其更改为:
go func() { fmt.Println(<-ch) }()
然后它将围绕 ch
创建一个闭包,然后匿名例程将被阻塞,而不是主线程,它可以继续到 send()
。
我正在尝试了解 goroutines。 在下面的示例中,为什么 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)
}
您看到错误是因为读取不是发生在 goroutine 内部,而是发生在主线程中。
行:
go fmt.Println(<-ch)
正在主线程中评估参数,一旦成功,它将 运行 goroutine 中的 Println
与已经解析的参数。由于代码永远无法在此状态下写入 ch
,因此它会死锁。
您可以将其更改为:
go func() { fmt.Println(<-ch) }()
然后它将围绕 ch
创建一个闭包,然后匿名例程将被阻塞,而不是主线程,它可以继续到 send()
。