在GO教程中,我们有以下幻灯片:戈鲁廷斯
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")
}运行此代码将产生预期的结果("world“和"hello”交替写入屏幕5次)。
但是,如果我们注释掉time.Sleep (因此,导入的"time"行)并再次运行程序,则只剩下只在屏幕上写了5次 "hello“。
time.Sleep有什么重要的,能让它免于死亡呢?
发布于 2013-04-02 18:27:12
如果删除time.Sleep,就不会给say("world") goroutine一个运行的机会。goroutine调度程序不是抢占性的。你的猩猩必须放弃控制,否则另一个峡谷将运行。放弃控制的一种方法是运行time.Sleep。
如果您从time.Sleep函数中取出say,那么主goroutine运行5次,而不放弃对次要goroutine的控制,然后当主goroutine从say返回时,程序退出,因为没有什么可以使程序存活。
发布于 2013-04-04 21:01:00
因为goroutine调度程序不是先发制人的,所以在另一个goroutine运行之前,您的goroutines必须放弃控制。放弃控制的一种方法是使用time.Sleep。另一种方法是使用runtime.Gosched()。
下面是修改后的教程,以使用戈斯普特():http://play.golang.org/p/jQ9mlGYXXE
这是理解猩猩的有用的一课。然而,试图直接控制调度程序肯定是一种反模式;悲伤往往会随之而来。
相反,要更多地考虑像通信数字硬件这样的大杂烩(状态机是一个很好的类比)。更好的方法是了解通信顺序过程模型,它是goroutines的基础。在基于CSP的设计中,每个goroutine都有自己的私有状态,并交换消息以与其他goroutines状态交互。消息的传递强制同步,调度程序使用同步来确定哪些活动获得cpu时间,哪些活动被放入等待队列。
当您接近这种方式时,您可能根本不需要担心调度程序内部的问题。
发布于 2016-06-07 23:36:23
如果从say函数中删除time.Sleep,则main将执行say("hello")并在不执行goroutine的情况下终止。如果在主端之前添加time.Sleep (或其他情况下为select {}),则会给goroutine提供运行时间,并且将从调度程序中选择该线程。
示例:
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")
time.Sleep(1*time.Second)
// Vs:
// select {} // blocks indefinitely, requires manual interrupt
// In CSP-speak the empty select is like STOP.
// for{} would cause the cpu to max and the process's STATE will be `running`
// select{} will not cause the cpu to max and the process state will be `sleeping`
}输出通常是5 hello,后面是5 world,但它也可以在最后一次hello之前打印出其中的一个世界。
-> (http://) goo.gl/K2v7H0 )
https://stackoverflow.com/questions/15771232
复制相似问题