为什么这个程序无法使用goroutine打印任何内容?

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

Why can't this program print anything using goroutine?

问题

我最近在研究谷歌的Golang,并遇到了以下问题。然后程序没有打印任何内容。但是如果我删除"go"标记,它将打印出"goroutine"和"going"两个词。

package main

import "fmt"

func f(msg string) {
    fmt.Println(msg)
    return
}

func main() {
    go f("goroutine")

    go func(msg string) {
        fmt.Println(msg)
        return
    }("going")

    return
}
英文:

I'm recently looking into Golang by google and I met with the following problem. Then program doesn't print anything. But if I remove the "go" notations, it will print both "goroutine" and "going".

package main

import "fmt"

func f(msg string) {
	fmt.Println(msg)
	return
}

func main() {
	go f("goroutine")

	go func(msg string) {
		fmt.Println(msg)
		return
	}("going")

	return
}

答案1

得分: 8

你的程序在goroutine执行之前就退出了。你可以稍微等待一下,例如通过调用time.Sleep(2 * time.Second),但这种行为被认为是不好的实践,因为你的程序可能运行时间超过2秒,然后仍然终止。

更好的方法是使用sync.WaitGroup

package main

import (
	"fmt"
	"sync"
)

func f(msg string, wg *sync.WaitGroup) {
	fmt.Println(msg)
	wg.Done()
}

func main() {
	var wg sync.WaitGroup

	wg.Add(1)
	go f("goroutine", &wg)

	wg.Add(1)
	go func(msg string) {
		fmt.Println(msg)
		wg.Done()
	}("going")
	
	wg.Wait()
}
英文:

You program exits before the goroutines is executed. You could wait a little bit, for example by calling time.Sleep(2 * time.Second), but such behaviour is considered bad practice, since your program could run longer than 2 seconds and would then terminate nonetheless.

A better approach is to use sync.WaitGroup:

package main

import (
	"fmt"
	"sync"
)

func f(msg string, wg *sync.WaitGroup) {
	fmt.Println(msg)
	wg.Done()
}

func main() {
	var wg sync.WaitGroup

	wg.Add(1)
	go f("goroutine", &wg)

	wg.Add(1)
	go func(msg string) {
		fmt.Println(msg)
		wg.Done()
	}("going")
	
	wg.Wait()
}

答案2

得分: 5

你的代码需要在退出之前等待例程完成。一种好的方法是传入一个通道,例程使用该通道来发出完成信号,然后在主代码中等待。请参考下面的代码。

这种方法的另一个优点是它允许/鼓励你根据返回值进行适当的错误处理。

package main

import (
	"fmt"
)

func f(msg string, quit chan int) {
	fmt.Println(msg)
	quit <- 0
	return
}

func main() {

	ch1 := make(chan int)
	ch2 := make(chan int)

	go f("goroutine", ch1)

	go func(msg string, quit chan int) {
		fmt.Println(msg)
		quit <- 0
		return
	}("going", ch2)

	<-ch1
	<-ch2
	return
}
英文:

Your code needs to wait for the routines to finish before exiting. A good way to do this is to pass in a channel which is used by the routine to signal when it's done and then wait in the main code. See below.

Another advantage of this approach is that it allows/encourages you to perform proper error handling based on the return value.

package main

import (
	&quot;fmt&quot;
)

func f(msg string, quit chan int) {
	fmt.Println(msg)
	quit &lt;- 0
	return
}

func main() {

	ch1 := make(chan int)
	ch2 := make(chan int)

	go f(&quot;goroutine&quot;, ch1)

	go func(msg string, quit chan int) {
		fmt.Println(msg)
		quit &lt;- 0
		return
	}(&quot;going&quot;, ch2)

	&lt;-ch1
	&lt;-ch2
	return
}

huangapple
  • 本文由 发表于 2014年2月14日 01:23:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/21761172.html
匿名

发表评论

匿名网友

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

确定