在 1.5 之前的 Go 版本中,一段涉及到 runtime.Gosched() 的代码被观察到影响输出程序:
func say(s string) { for i := 0; i < 5; i++ { runtime.Gosched() fmt.Println(s) } } func main() { go say("world") say("hello") }
带runtime.Gosched()的输出:
hello world hello world hello world hello world hello
不带runtime.Gosched()的输出:
hello hello hello hello hello
在 1.5 之前的 Go 版本中,runtime.Gosched() 显式地将控制权交给了其他被调用时的 goroutine。虽然 Go 程序默认在单个操作系统线程上运行,但 runtime.Gosched() 允许调度程序在 goroutine 之间切换执行。
当 GOMAXPROCS 未设置或设置为 1 时,Go 的协作多任务处理需要 goroutine 显式让出控制权。因此,在上面的代码示例中,“world”输出仅在调用 runtime.Gosched() 时出现,因为它允许调度程序切换到运行“world”打印语句的 goroutine。
在 Go 1.5 及更高版本中,runtime.GOMAXPROCS 默认设置为硬件核心数,这意味着 Go 可能会创建多个 OS 线程运行 goroutines。
将 GOMAXPROCS 设置为大于 1 的值,goroutine 可以并行运行。然而,与抢占式多任务系统不同,goroutines 仍然必须显式地让出控制权以允许其他 goroutine 执行。这是因为 Go 使用协作式多任务处理,其中 goroutine 自愿将控制权交给调度程序。
当 GOMAXPROCS 设置为大于 1 的值时,交错 goroutine 的结果可能会变得不确定,因为调度程序可以随时在它们之间切换执行。这可能会导致不可预测的输出模式,如上面的示例所示,当 GOMAXPROCS 设置为 2 时。
以上是在 Go 1.5 之前和之后,`runtime.Gosched()` 对 Go 程序的执行有何影响?的详细内容。更多信息请关注PHP中文网其他相关文章!