为什么我的 goroutine 没有执行?

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

Why is my goroutine not executed?

问题

我正在学习Go语言,想尝试使用goroutine和channel。

以下是我的代码:

package main
import "fmt"
func main(){

    messages := make(chan string,3)

    messages <- "one"
    messages <- "two"
    messages <- "three"

    go func(m *chan string) {
        fmt.Println("进入goroutine...")
        for {
            fmt.Println(<- *m)
        }
    }(&messages)

    fmt.Println("完成!")
}

以下是结果:

完成!

我不明白为什么我的goroutine没有被执行。没有打印出"进入goroutine",也没有错误信息。

英文:

I'm learning Go and I wanted to try goroutines and channels.

Here's my code:

package main
import &quot;fmt&quot;
func main(){

messages := make(chan string,3)

messages &lt;- &quot;one&quot;
messages &lt;- &quot;two&quot;
messages &lt;- &quot;three&quot;

go func(m *chan string) {
	fmt.Println(&quot;Entering the goroutine...&quot;)
	for {
		fmt.Println(&lt;- *m)
	}
}(&amp;messages)

fmt.Println(&quot;Done!&quot;)
}

And here's the result:

Done!

I don't understand why my goroutine is never executed. The "Entering the goroutine" is not printed and I don't have any error message.

答案1

得分: 35

事实是,你的goroutine开始了,但在执行任何操作之前就结束了,因为你的程序在打印Done!后立即停止:goroutine的执行是独立于主程序的,但会在程序停止时一起停止。所以基本上,你需要一些处理来让程序等待它们。可以是另一个等待一定数量消息的通道,一个sync.WaitGroup,或其他技巧。

你应该阅读一下golang博客中关于并发的优秀文章《Go中的并发模式:超时和取消》

英文:

The fact is that your goroutine starts, but is ended before doing anything because your program stop right after printing Done!: execution of goroutines is independant of the main program, but will be stopped at the same than the program. So basically, you need some process to make the program wait for them. It could be another channel waiting for a number of messages, a sync.WaitGroup, or other tricks.

You should read the excellent post about concurrency in go in the golang blog.

答案2

得分: 12

你的 Goroutine 没有足够的时间来执行,因为主函数在打印 Done! 后就退出了。

你需要做一些事情来让程序等待 Goroutine。

最简单的方法是在最后添加一个 time.Sleep()

package main

import (
	"fmt"
	"time"
)

func main() {

	messages := make(chan string, 3)

	messages <- "one"
	messages <- "two"
	messages <- "three"

	go func(m *chan string) {
		fmt.Println("进入 Goroutine...")
		for {
			fmt.Println(<-*m)
		}
	}(&messages)
	time.Sleep(5 * time.Second)
	fmt.Println("完成!")
}

进入 Goroutine...
one
two
three
完成!

Playground

虽然这样可以工作,但建议在并发代码中使用通道或 sync 包中的函数来与 Goroutine 同步。

示例:

package main

import (
	"fmt"
)

func main() {

	messages := make(chan string, 3)
	go func(m chan string) {
		defer close(m)
		fmt.Println("进入 Goroutine...")
		messages <- "one"
		messages <- "two"
		messages <- "three"
	}(messages)
	for message := range messages {
		fmt.Println("接收到", message)
	}
	fmt.Println("完成!")
}

进入 Goroutine...
接收到 one
接收到 two
接收到 three
完成!

Playground

英文:

Your Goroutine doesn't have enough time to execute, as the main function exits after printing Done!.

You need to do something to make the program wait for the Goroutine.

The easiest way is to add a time.Sleep() to the end.

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {

	messages := make(chan string, 3)

	messages &lt;- &quot;one&quot;
	messages &lt;- &quot;two&quot;
	messages &lt;- &quot;three&quot;

	go func(m *chan string) {
		fmt.Println(&quot;Entering the goroutine...&quot;)
		for {
			fmt.Println(&lt;-*m)
		}
	}(&amp;messages)
	time.Sleep(5 * time.Second)
	fmt.Println(&quot;Done!&quot;)
}

>Entering the goroutine...
one
two
three
Done!

Playground

While this works, it's recommended to use channels, or functions from the sync package, in addition to goroutines, to synchronize concurrent code.

Example:

package main

import (
	&quot;fmt&quot;
)

func main() {

	messages := make(chan string, 3)
	go func(m chan string) {
		defer close(m)
		fmt.Println(&quot;Entering the goroutine...&quot;)
		messages &lt;- &quot;one&quot;
		messages &lt;- &quot;two&quot;
		messages &lt;- &quot;three&quot;
	}(messages)
	for message := range messages {
		fmt.Println(&quot;received&quot;, message)
	}
	fmt.Println(&quot;Done!&quot;)
}

>Entering the goroutine...
received one
received two
received three
Done!

Playground

huangapple
  • 本文由 发表于 2014年6月26日 16:38:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/24425987.html
匿名

发表评论

匿名网友

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

确定