runtime.GOMAXPROCS(2)不管用

最近遇到的问题,下面的代码已经设置了runtime.GOMAXPROCS为2,那么至少会有两个P,也就是能用到两个M(即两个内核线程),所以这个程序的输出应该是不停的输出数字,但是实际情况却是输出一定数字后就hang了:

package main

import "fmt"
import "runtime"
import "time"

func forever() {
    for {
    }   
}

func show() {
    for number := 1; number < 999999; number++ {
        time.Sleep(1000)
        fmt.Println(number)
    }   
}

func main() {
    runtime.GOMAXPROCS(2)
    go show()
    go forever()
    for {
        time.Sleep(1000)
    }   
} 

大家可以跑一下这个代码,看下自己的实际输出。

为什么会这样呢?看了线程数也证明M确实增加了。。。原因在于GO中存在runtime的G,GC就是其中之一。目前的GC要求有一个stop-the-world的步骤,也就是停止所有的G然后开始GC。但当某一个G是个纯粹的消耗CPU是死循环的时候,这个G没有办法把时间片交给runtime,那么GC的G也就无法完成stop-the-world,因此会造成整个程序假死的现象。

如果证明是GC的原因呢?一个方法是去看GO的代码啦,还有一个办法就是:

[root@dev g]# export GOGC=off 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*