goroutine值返回顺序

时间:2018-06-09 07:09:24

标签: go goroutine

为什么以下代码始终返回2,1而不是1,2。

func test(x int, c chan int) {
   c <- x
}

func main() {
    c := make(chan int)
    go test(1, c)
    go test(2, c)
    x, y := <-c, <-c // receive from c
    fmt.Println(x, y)
}

1 个答案:

答案 0 :(得分:2)

如果您想知道订单是什么,请让您的程序包含订购信息

此示例使用函数闭包生成序列

通道返回两个数字的结构,其中一个是序列号

由于序列计数器上有一个互斥锁,序列增量器应该在每个例程中都是安全的

package main

import (
    "fmt"
    "sync"
)

type value_with_order struct {
    v     int
    order int
}

var (
    mu sync.Mutex
)

func orgami(x int, c chan value_with_order, f func() int) {
    v := new(value_with_order)
    v.v = x
    v.order = f()
    c <- *v
}
func seq() func() int {
    i := 0
    return func() int {
        mu.Lock()
        defer mu.Unlock()
        i++
        return i
    }
}

func main() {

    c := make(chan value_with_order)
    sequencer := seq()
    for n := 0; n < 10; n++ {
        go orgami(1, c, sequencer)
        go orgami(2, c, sequencer)
        go orgami(3, c, sequencer)
    }
    received := 0
    for q := range c {
        fmt.Printf("%v\n", q)
        received++
        if received == 30 {
            close(c)
        }
    }

}

第二个版本,其中从主循环调用序列以使序列号按照调用函数的顺序出现

package main

import (
    "fmt"
    "sync"
)

type value_with_order struct {
    v     int
    order int
}

var (
    mu sync.Mutex
)

func orgami(x int, c chan value_with_order, seqno int) {
    v := new(value_with_order)
    v.v = x
    v.order = seqno
    c <- *v
}
func seq() func() int {
    i := 0
    return func() int {
        mu.Lock()
        defer mu.Unlock()
        i++
        return i
    }
}

func main() {

    c := make(chan value_with_order)
    sequencer := seq()
    for n := 0; n < 10; n++ {

        go orgami(1, c, sequencer())
        go orgami(2, c, sequencer())
        go orgami(3, c, sequencer())
    }
    received := 0
    for q := range c {
        fmt.Printf("%v\n", q)
        received++
        if received == 30 {
            close(c)
        }
    }

}
相关问题