一个考并发的面试题,怎么答??

今天面试做笔试,遇到这道题

package main

import (
    "fmt"
    "runtime"
    "sync"
    "time"
)

func main() {
    runtime.GOMAXPROCS(1)

    var wg sync.WaitGroup
    wg.Add(10)

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

    wg.Wait()
}

我的回答是输出值不确定

更新: 多谢h12朋友指出 我做题时注意到了wait之后,goroutines才会有执行机会 也注意到了i的取值,但忽略了两者的关联 粗心了,活该被刷掉

已邀请:

wshlovercn

赞同来自: yuancx gonewbie

应该说,结果还是不确定的。虽然大多数情况下输出结果稳定。 runtime.GOMAXPROCS(1) 并不意味着main routine 会一直占用唯一的线程。 所以在这种场景下,其他routine 的执行时机不确定。 可以看下如下修改:

package main

import ( "fmt" "math/rand" "runtime" "sync" )

func main() { runtime.GOMAXPROCS(1)

var wg sync.WaitGroup
wg.Add(10)

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

    if i % 3 == 0 {
        for j := 0; j < 1000000; j++ {
            r := rand.Intn(10000)
            r = r * r
        }
    }
}

wg.Wait()

}

h12 - https://h12.io/about

赞同来自: heramerom

因为runtime.GOMAXPROCS(1),main函数所在的goroutine占用唯一的线程直到wg.Wait()才挂起。这时循环已经结束i==10,其他routines才有机会依次启动。。。

wshlovercn

赞同来自: gonewbie

Goroutine的执行是可以被抢占的。如果一个Goroutine一直占用CPU,长时间没有被调度过, 就会被runtime抢占掉,把CPU时间交给其他Goroutine。

可以参考这个文章: http://ga0.github.io/golang/2015/09/20/golang-runtime-scheduler.html

从我的代码也可以说明这个main routine 确实被强占过,否则其他routine 不会被执行。

一般来说,这种依赖执行时间的顺序的方式,都不太可靠。

mibesr

赞同来自:

@wshlovercn 关于 “runtime.GOMAXPROCS(1) 并不意味着main routine 会一直占用唯一的线程” ,不太理解,可否详细解释一下,谢谢!

要回复问题请先登录注册