Gorutins always execute & ldquo; Last in first out & rdquo;

微信扫一扫,分享到朋友圈

Gorutins always execute & ldquo; Last in first out & rdquo;

in the interests of learning more about Go, I have been playing with goroutines, and have noticed something – but am not sure what exactly I’m seeing, and hope someone out there might be able to explain the following behaviour.

the following code does exactly what you’d expect:

package main

import (
  "fmt"
)

type Test struct {
  me int
}

type Tests []Test

func (test *Test) show() {
  fmt.Println(test.me)

}

func main() {
  var tests Tests
  for i := 0; i < 10; i++ {
    test := Test{
      me: i,
    }
    tests = append(tests, test)
  }

  for _, test := range tests {
    test.show()
  }

}

and prints 0 – 9, in order.

now, when the code is changed as shown below, it always returns with the last one first – doesn’t matter which numbers I use:

package main

import (
    "fmt"
    "sync"
)

type Test struct {
    me int
}

type Tests []Test

func (test *Test) show(wg *sync.WaitGroup) {
    fmt.Println(test.me)
    wg.Done()

}

func main() {
    var tests Tests
    for i := 0; i < 10; i++ {
        test := Test{
            me: i,
        }
        tests = append(tests, test)
    }

    var wg sync.WaitGroup
    wg.Add(10)
    for _, test := range tests {
        go func(t Test) {
            t.show(&wg)
        }(test)
    }
    wg.Wait()

}

this will return: 9 0 1 2 3 4 5 6 7 8

the order of iteration of the loop isn’t changing, so I guess that it is something to do with the goroutines… basically, I am trying to understand why it behaves like this…I understand that goroutines can run in a different order than the order in which they’re spawned, but, my question is why this always runs like this. as if there’s something really obvious I’m missing…

As expected, the ouput is pseudo-random,

package main

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

type Test struct {
    me int
}

type Tests []Test

func (test *Test) show(wg *sync.WaitGroup) {
    fmt.Println(test.me)
    wg.Done()

}

func main() {
    fmt.Println("GOMAXPROCS", runtime.GOMAXPROCS(0))
    var tests Tests
    for i := 0; i < 10; i++ {
        test := Test{
            me: i,
        }
        tests = append(tests, test)
    }

    var wg sync.WaitGroup
    wg.Add(10)
    for _, test := range tests {
        go func(t Test) {
            t.show(&wg)
        }(test)
    }
    wg.Wait()

}

Output:

$ go version
go version devel +af15bee Fri Jan 29 18:29:10 2016 +0000 linux/amd64
$ go run goroutine.go
GOMAXPROCS 4
9
4
5
6
7
8
1
2
3
0
$ go run goroutine.go
GOMAXPROCS 4
9
3
0
1
2
7
4
8
5
6
$ go run goroutine.go
GOMAXPROCS 4
1
9
6
8
4
3
0
5
7
2
$

Are you running in the Go playground? The Go playground, by design, is deterministic, which makes it easier to cache programs.

Or, are you running with runtime.GOMAXPROCS = 1? This runs one thing at a time, sequentially. This is what the Go playground does.

微信扫一扫,分享到朋友圈

Gorutins always execute & ldquo&semi; Last in first out & rdquo&semi;

电影如何破圈、跨界?张艺谋新作《影》想用「品牌联营」全面触达用户

上一篇

单例模式之Java和Kotlin版

下一篇

你也可能喜欢

Gorutins always execute & ldquo&semi; Last in first out & rdquo&semi;

长按储存图像,分享给朋友