单核CPU协程调度问题

设置单核执行,在go1.12上,为什么总是打印func4呢? 按道理讲不应该是优先打印出func1吗?

package main

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

type query func(string) string

func exec(name string, vs ...query) string {
    ch := make(chan string)
    fn := func(i int) {
        fmt.Println("i->",i)
        ch <- vs[i](name)
    }
    for i := range vs {

        go fn(i)
    }
    return <-ch
}

func main() {
    runtime.GOMAXPROCS(1)
    ret := exec("111", func(n string) string {
        return n + "func1"
    }, func(n string) string {
        return n + "func2"
    }, func(n string) string {
        return n + "func3"
    }, func(n string) string {
        return n + "func4"
    })
    fmt.Println(ret)
}
已邀请:

json_

赞同来自:

专门注册账号来回复你 channal 在你的方法中,channal值取出来了一个值,因此值输出一个。 可以改成下面这样

package main

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

type query func(string) string

func exec(name string, vs ...query) string {
    ch := make(chan string)
    fn := func(i int) {
        fmt.Println("i->", i)
        ch <- vs[i](name)
    }
    fun :=func(i int) {
        fmt.Println(i,"<-i",<-ch)
    }
    for i := range vs {
        go fn(i)
    }
    for i := range vs {
        go fun(i)
    }
    return ""
}

func main() {
    runtime.GOMAXPROCS(1)
    ret := exec("111", func(n string) string {
        return n + "func1"
    }, func(n string) string {
        return n + "func2"
    }, func(n string) string {
        return n + "func3"
    }, func(n string) string {
        return n + "func4"
    })
    fmt.Println(ret)
    time.Sleep(time.Second)
}

输出

i-> 0
3 <-i 111func1
i-> 2
0 <-i 111func3
i-> 1
1 <-i 111func2
i-> 3
2 <-i 111func4

你的输出和我的输出一定不一样,因为数据存入channal的顺序就是不确定的。

hedakui - 90后it男

赞同来自:

说下我的个人理解啊, golang中线程遇到代码堵塞就会挂起然后去执行其他内容。runtime.GOMAXPROCS(1) 后只会有一个线程来执行代码,这个线程会执行完成非coroutine,和非堵塞的代码后再去执行coroutine里面的代码。你的代码中exec 函数 执行到最后遇到 <-ch 堵塞代码了,所以会去执行coroutine,这个时候i的值由于for循环已经走完了,所以i=3。会去调用你最后一个函数

要回复问题请先登录注册