https://tour.go-zh.org/concurrency/1
package mainimport (
"fmt"
"time"
//"runtime"
)func say(s string) {
for i := 0;
i < 5;
i++ {
time.Sleep(1 * time.Millisecond)
//runtime.Gosched()
fmt.Println(s,time.Now().UnixNano()/1e6)
}
}func main() {
go say("world")
//runtime.Gosched()
say("hello")
//time.Sleep(1*time.Millisecond)
}
教程里运行在虚拟环境里,每次执行的结果都一样,实际上,在本地电脑上执行,每次结果都不一样,hello/world先后随机
文章图片
【Go goroutine】time.Sleep有必要,因为goroutine不是preemptive(抢占式),如果main goroutine不加time.sleep(或者runtime.Gosched())放弃控制权,go 命令指定的新goroutine不会得到执行;或者sync.WaitGroup
If you remove the
time.Sleep
you don't give the say("world")
goroutine a chance to run. The goroutine scheduler is not preemptive. Your goroutines have to give up control before another goroutine will run. One way to give up control is to run time.Sleep
.If you take out the
time.Sleep
from the say
function then the primary goroutine runs 5 times without giving up control to the secondary goroutine and then when the primary goroutine returns from say
the program exits because there is nothing to keep the program alive.https://stackoverflow.com/questions/15771232/why-is-time-sleep-required-to-run-certain-goroutines
https://stackoverflow.com/questions/29654328/go-lang-why-go-routine-function-never-being-called?noredirect=1&lq=1
并发编程,程序执行时间点不可靠
The compiler will insert yield points into your program at different locations where it seems adequate. For example, in some function calls and seemingly tight loops. Also, a goroutine will yield when blocking on a syscall. So your program will probably yield execution over to the second goroutine when the first goroutine reaches
fmt.Println("World")
and enters a write syscall. After that non-determinism ensues because we don't know how long this syscall will take.This, however, is an implementation detail and you should not be concerned with it. When talking about parallelism, the only timing guarantees (i.e. "happens before") you have are those provided by concurrency primitives like those from the standard library's
sync/atomic
package.TL; DR: Don't rely on yield points for your program to work correctly.
https://stackoverflow.com/questions/30935947/what-is-the-execution-time-point-of-goroutine?noredirect=1&lq=1
推荐阅读
- Go|Docker后端部署详解(Go+Nginx)
- GO|GO,GO,GO!
- Go成长之路|go中判断空字符串、nil和len(t)的用法
- go编译tools
- go grpc安装与使用
- goroutine 调度原理
- Go|Go进阶之路——复杂类型
- Go进阶之路——变量
- Go进阶之路——流程控制语句