Golang例程提前终止

时间:2016-10-29 03:12:42

标签: go

我刚开始使用go并编写了我的第一个程序,但输出并不像预期的那样。我写了一个异步例程addUrl,它将url添加到通道5000次并且consumeUrl从通道中删除并打印它。 该例程仅运行9次。为什么?下面是代码和输出

package main

import "fmt"
import "time"

var urlCount = 0

func main(){

    urlHolder := make(chan string,5000)

    fmt.Printf("Starting program")

    go addUrls(urlHolder)

    time.Sleep(time.Millisecond * 100)
    go consumeUrls(urlHolder)

    fmt.Printf("Done")

}

func addUrls(urlHolder chan string){
    var myurl string = "https://example.com/"

    for i:=0; i<5000 ; i++ {
        urlHolder<-myurl
        fmt.Printf(" %d url added \n",i)
        time.Sleep(time.Millisecond * 10)
    }

}

func consumeUrls(urlHolder chan string) {
    urlCount++
    urlsConsumed := <- urlHolder
    fmt.Printf("Pulled url %d",urlCount," ",urlsConsumed,"\n")
    time.Sleep(time.Millisecond * 20)
}  

输出

Starting program
 0 url added 
 1 url added 
 2 url added 
 3 url added 
 4 url added 
 5 url added 
 6 url added 
 7 url added 
 8 url added 
Done

当循环为5000时,为什么它终止于8?

2 个答案:

答案 0 :(得分:1)

您正在使用time.Sleep等待main完成,但您确实应该使用WaitGroups。

通过这种方式,您不必尝试选择一些任意时间,并希望它足以让您的程序完成,或者担心设置太多时间而您的程序无所事事。

我已将WaitGroups的实现添加到您的代码中:

  

https://play.golang.org/p/1zn2JYefaA

此外,写consumeUrls函数的方式不能正常循环,您不会打印通道中的所有内容。但由于这不是你的具体问题,我不会在这里解决。

答案 1 :(得分:-1)

实际上问题就像尼彭说的那样,主要是提前终止了。