主要是由于 goroutine 的原因,导致主程序退出得太快。

huangapple go评论69阅读模式
英文:

main exiting to soon, due to goroutine

问题

我正在尝试重新实现/修改此帖子的第二个评论中的代码。

我想要多个goroutine从堆栈中弹出元素(只要堆栈中还有元素),并且另一个函数来接收它们。

以下是在playground中的代码:链接

func pop(list *[]int, c chan int) {
    if len(*list) != 0 {
        result := (*list)[0]
        *list = (*list)[1:]
        fmt.Println("about to send ", result)
        c <- result
    } else {
        return
    }
}

func receiver(c chan int) {
    result := <-c
    fmt.Println("received ", result)
}

var list = []int{1, 2, 3}

func main() {
    fmt.Println("Main")
    c := make(chan int)
    go pop(&list, c)
    go pop(&list, c)
    receiver(c)
    fmt.Scan()
}

如果我将receiver(c)改为一个goroutine,只会打印出"Main",并且程序将在不等待Scan()函数的情况下退出。即使添加time.Sleep(2)也无法阻止程序退出。

为什么我的程序在没有任何输入的情况下退出?

英文:

I am trying to reimplement / modify the code of the second comment of this post.

I would like multiple go routines to pop elements from the stack (as long as the stack contains something), and another function to catch them.

This code in playground

func  pop(list *[]int, c chan int) {
    if len(*list) != 0 {
        result := (*list)[0]
        *list = (*list)[1:]
        fmt.Println(&quot;about to send &quot;,result)
        c &lt;-  result
    } else {return}
}

func receiver (c chan int){
    result := &lt;- c
    fmt.Println(&quot;received &quot;, result)
}

var list = []int{1, 2, 3}

func main() {

fmt.Println(&quot;Main&quot;)
c := make(chan int)
go pop (&amp;list, c)
go pop (&amp;list,c)
receiver(c)
fmt.Scan()

If I make receiver(c) a go routine, only "Main" will be printed, and the program will exit without waiting for the Scan() function. Even adding a time.Sleep(2) won't prevent the program from exiting.

Why is my program exiting without any input?

答案1

得分: 2

Scan函数在没有参数的情况下不会阻塞。

请注意,即使给Playground传递参数,它也不会在IO上阻塞,比如以下代码:

var i int
fmt.Scan(&i)

即使你检查它返回的error值(第二个返回值),你会发现它报告了error: EOF,但这个示例在Playground之外会阻塞。

编辑:如果你想要在输入时阻塞而不创建一个虚拟变量,可以使用Scanln函数,但在Playground上仍然会失败。

英文:

Scan will not block if given zero arguments.

Note that the Playground will not block on IO even if you give it an argument, the code

var i int
fmt.Scan(&amp;i)

Also will fail to block, if you check the error value it returns (the second return value), which you should, you'll see it reports error: EOF.

(Though that sample will block outside the Playground).

Edit: If you want to block on input without making a dummy variable, use Scanln, though it still will fail on the Playground.

huangapple
  • 本文由 发表于 2014年9月19日 10:05:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/25925244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定