Go goroutine

博客围绕Go语言并发编程展开,指出教程在虚拟环境执行结果固定,本地执行结果随机,hello/world先后顺序不定。强调time.Sleep的必要性,因goroutine非抢占式,不加该操作新goroutine可能无法执行。还提及并发编程中程序执行时间点不可靠的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://tour.go-zh.org/concurrency/1

package main

import (
	"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先后随机


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


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值