在GO教程中,我们有这张幻灯片:Goroutines
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
Run Code Online (Sandbox Code Playgroud)
运行此代码会产生预期的结果("world"和"hello"可互换地写入屏幕5次).
但是,如果我们注释掉time.Sleep(因此,"time"导入的行)并再次运行程序,我们只剩下 "hello"写入屏幕五次.
什么是如此重要time.Sleep才能使goroutine免于死亡?
Dan*_*iel 34
如果你删除了time.Sleep你不给say("world")goroutine一个机会跑.goroutine调度程序不是抢占式的.你的goroutines必须在另一个goroutine运行之前放弃控制.放弃控制的一种方法是运行time.Sleep.
如果time.Sleep从say函数中取出,则主goroutine运行5次而不放弃对辅助goroutine的控制,然后当say主程序从程序返回时退出,因为没有任何东西可以使程序保持活动状态.
因为goroutine调度程序不是抢占式的,所以你的goroutine必须在另一个goroutine运行之前放弃控制.放弃控制的一种方法是time.Sleep.另一种方式是runtime.Gosched().
这是修改为使用Gosched()的教程:http://play.golang.org/p/jQ9mlGYXXE
这是理解goroutines的有用教训.但是,试图直接控制调度程序绝对是一种反模式; 悲伤往往会随之而来.
相反,更多地考虑像沟通数字硬件的大块(状态机是一个很好的比喻).最好学习goroutine所基于的Communicating Sequential Processes模型.在基于CSP的设计中,每个goroutine都有自己的私有状态,并交换消息以与其他goroutine的状态进行交互.消息的传递会强制同步,调度程序使用该同步来确定哪些活动获取cpu时间以及将哪些内容放入等待队列.
当你以这种方式接近Go时,你可能永远不必担心调度程序内部.
| 归档时间: |
|
| 查看次数: |
12912 次 |
| 最近记录: |