for死循环和多线程问题

代码1:

package main

import (
    "fmt"

)

func main() {
    go foo()

    for {
    }
}

func foo() {
    fmt.Println("fooo")
}

执行结果:无法输出 "fooo"

代码2:

package main

import (
    "fmt"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    go foo()
    for {
    }
}

func foo() {
    fmt.Println("fooo")
}

执行结果:输出 "fooo",死循环。

想问一句,为什么?

共 4 个回复


keepeye

我的粗浅理解: 单核心线程情况下,for循环无法挂起并切换到别的goroutine。多核心的情况下却可以?

# 0

keepeye

package main

import (
    "fmt"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    go foo()
    go foo()
    go foo()
    go foo()
    for {
    }
}

func foo() {
    fmt.Println("fooo")
    for {
    }
}

测试了一下这样的代码,发现输出了3行"fooo",而第四行却没有。 可以认为:
在单线程时,其他goroutine任务只能等当前goroutine主动挂起(比如chan阻塞)才会切换。多线程时,在go foo()的时候就直接把这个goroutine放到其他线程中了,不受当前线程死循环影响。

# 1

stevewang

因为for{}就是死循环。

# 2

snake117

死循环和阻塞不一样。

go的多线程切换机制换了好几次了。以前的时候,我记得有设定说如果一个go程执行时间较长会强制切换的;后来好像换成竞争上岗了,之后也有修改,反正我是不明白怎么回事了。

# 3