当主要范围结束时,不会调用goroutine的延迟

6 go

package main

import(
    "fmt"
    "time"
)

func main(){
    fmt.Println("1")
    defer fmt.Println("-1")
    go func() { 
        fmt.Println("2")
        defer fmt.Println("-2")
        time.Sleep(9 * time.Second)
    }()
    time.Sleep(1 * time.Second)
    fmt.Println("3")
}
Run Code Online (Sandbox Code Playgroud)

产生输出:1 2 3 -1但是我会认为goroutine的推迟会被称为产生:1 2 3 -2 -1

在我的实际代码中,我的goroutine被阻止在websocket上...我想我可以发送一个关闭信号,但我还没有弄清楚如何做一个等待多对象的事情(如果它实际上可以在go)完成.我正在通过将延迟-2提升到主范围来解决我的问题.

是否有一些技巧推迟放置我做得不对?

http://play.golang.org/p/qv8UEuF2Rb

小智 5

(我没有足够的代表发表评论?)

是的,问题在于goroutine调度并且与平台有关.使用带有goroutine的函数末尾的runtime.Gosched来确保它获得一些cputime.目前在x86_64 linux上,下面的代码将产生"3"但没有Gosched它会产生"1":

不,这不是问题,只能通过共同发生(通过实施细节)来解决.正如已经在goroutine的暗示中暗示的那样,当主要范围结束时没有被调用.你的代码是活泼的,因此你必须明确地同步goroutines.最简单的方法是使用频道或等待组http://golang.org/pkg/sync/#WaitGroup.哪个选项更合适取决于您正在做什么.如果您只想等待一些结果,那么让gorutine将其结果发送到频道,您只需等待它.如果您只想等待一些goroutine,那么请使用waitgroup.