dqr91899 2015-07-23 20:07
浏览 56
已采纳

MacOS和Linux上go1.5beta2中的不同行为

The example is taken from the "A Tour of Go": https://tour.golang.org/concurrency/1

Obviously, program output should have 10 rows: 5 for "hello" and 5 for "world".

But we have on:

  • Linux - 9 rows
  • MacOS - 10 rows

Linux output (9 rows):

$ go run 1.go 
hello
world
hello
world
hello
world
world
hello
hello

MacOS X output (10 rows):

$ go run 1.go 
hello
world
world
hello
hello
world
hello
world
hello
world

Can anyone explain - why?

Linux uname -a:

Linux desktop 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt11-1 (2015-05-24) x86_64 GNU/Linux

MacOS X uname -a:

Darwin 14.5.0 Darwin Kernel Version 14.5.0: Thu Jul  9 22:56:16 PDT 2015; root:xnu-2782.40.6~1/RELEASE_X86_64 x86_64

Source code from tour:

package main

import (
    "fmt"
    "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(1000 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
}
  • 写回答

1条回答 默认 最新

  • doqp87012 2015-07-24 00:20
    关注

    From the specification:

    Program execution begins by initializing the main package and then invoking the function main. When that function invocation returns, the program exits. It does not wait for other (non-main) goroutines to complete.

    So there is no guarantee that the goroutine printing "world" will have time to complete before the program exits.

    I suspect that if you run the program enough times, you will see both the 9-line and 10-line outputs on both platforms. Setting the GOMAXPROCS environment variable to 2 might also help in triggering the problem.

    You can fix it by making the main goroutine explicitly wait for completion of the other goroutine. For instance, using a channel:

    func say(s string, done chan<- bool) {
        for i := 0; i < 5; i++ {
            time.Sleep(1000 * time.Millisecond)
            fmt.Println(s)
        }
        done <- true
    }
    
    func main() {
        c := make(chan bool, 2)
        go say("world", c)
        say("hello", c)
        <-c
        <-c
    }
    

    I've added a buffer to the channel so that the say function can send a value without blocking (primarily so the "hello" invocation actually returns). I then wait receive two values from the channel to make sure both invocations have completed.

    For more complex programs, the sync.WaitGroup type can provide a more convenient way to wait on multiple goroutines.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 fluent无法启动
  • ¥15 孟德尔随机化r语言运行问题
  • ¥15 pyinstaller编译的时候出现No module named 'imp'
  • ¥15 nirs_kit中打码怎么看(打码文件是csv格式)
  • ¥15 怎么把多于硬盘空间放到根目录下
  • ¥15 Matlab问题解答有两个问题
  • ¥15 LCD12864中文显示
  • ¥15 在使用CH341SER.EXE时不小心把所有驱动文件删除了怎么解决
  • ¥15 gsoap生成onvif框架
  • ¥15 有关sql server business intellige安装,包括SSDT、SSMS。