for真的会独占CPU吗?

kavinbright · 2023-05-28 22:10:21 · 6107 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2023-05-28 22:10:21 的主题,其中的信息可能已经有所发展或是发生改变。

func main() {
    runtime.GOMAXPROCS(1)

    go func() {
        for i:=0;i<10 ;i++  {
            fmt.Println(i)
        }
    }()

    for {}
}

预想的是for独占M, goroutine不会执行,但是结果却是goroutine正常输出,这是为何?

0
1
2
3
4
5
6
7
8
9

我的go版本是:

☁  etc  go version
go version go1.17 darwin/amd64

我记得这个问题在《go语言高级编程》中提过。 求大佬们帮忙释怀。。。


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

6107 次点击  
加入收藏 微博
13 回复  |  直到 2023-07-07 15:34:24
buguang01
buguang01 · #2 · 2年之前

因为新版本的golang解决了你说的这个问题。

jan-bar
jan-bar · #3 · 2年之前

执行go tool compile -S test1.go > xx.txt你会发现for {}实际上被优化了,根本就不是一个循环

image.png

GO_go_GO1
GO_go_GO1 · #4 · 2年之前
jan-barjan-bar #3 回复

执行`go tool compile -S test1.go > xx.txt`你会发现`for {}`实际上被优化了,根本就不是一个循环 ![image.png](https://static.golangjob.cn/230529/f67793138f3f9b0e2ce90bb0fce6c795.png)

你确定不是go的调度 把阻塞的 协程放到其他cpu运行了?对for做了优化,没看懂这个 优化成啥了

GO_go_GO1
GO_go_GO1 · #5 · 2年之前

image.png

zhupp
zhupp · #6 · 2年之前

golang是抢占式的调度,如果一个协程阻塞,调度器会把cpu剥夺,让给其他协程。目的就是防止某个协程占用过多的cpu时间,防止其他协程饿死。

Neightly
Neightly · #7 · 2年之前

这种无法单凭某一个文件某一段代码就找到明确答案和依据的题目,很容易炸出“裸泳”者。

saberlong
saberlong · #8 · 2年之前

这个是go1.14版本更新时实现了基于信号的抢占式调度

abelli5
abelli5 · #9 · 2年之前

Windows操作系统从95版开始、Linux从2.0内核都是抢先式多任务了,保护模式和CPU核心数无瓜,哪怕只有一个核心的保护模式也支持抢先式多任务。golang协程只是使用了操作系统的特性而已。

Neightly
Neightly · #10 · 2年之前
abelli5abelli5 #9 回复

Windows操作系统从95版开始、Linux从2.0内核都是抢先式多任务了,保护模式和CPU核心数无瓜,哪怕只有一个核心的保护模式也支持抢先式多任务。golang协程只是使用了操作系统的特性而已。

你确定看过抢占的实现过程?

abelli5
abelli5 · #11 · 2年之前
NeightlyNeightly #10 回复

#9楼 @abelli5 你确定看过抢占的实现过程?

嗯教科书上是这么说的,实际测试也相符,一个核心也能输出。 如果想独占CPU的一个核心,在Windows上有相应的系统API,以前使用过。

geek
geek · #12 · 2年之前

之前是利用morestack插入了一段检测代码。但如代码,如果不涉及func调用,而是一个for{},那其他协程就一直得不到执行机会。 1.14实现了基于信号量的抢占式调度,其他协程也能得到执行机会了

alphayan
alphayan · #13 · 2年之前

以前确实会,查看状态一个核心是100%占用,后面版本不会了。

liyun
liyun · #14 · 2年之前

应该是因为协程的CPU占用时长问题,超过10ms会强制性把该协程放到global队列

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传