英文:
Need understanding of goroutines
问题
我是你的中文翻译助手,以下是你提供的代码的翻译:
我是Go语言编程的新手,正在逐步学习。在练习过程中,我发现goroutine的行为是随机的。如果我调用一个包含1秒睡眠的goroutine函数,有时它会成功完成,有时则不会:
package main
import (
	"fmt"
	"time"
)
func t(i int) {
	fmt.Println("In func t")
	time.Sleep(1)
}
func t1(i int) {
	fmt.Println("In func t1")
	time.Sleep(1)
}
func main() {
	fmt.Println("Hello Good Morning")
	go t(1)
	t1(2)
	time.Sleep(5)
	fmt.Println("End of func main")
}
输出1:
Hello Good Morning
In func t1
In func t
End of func main
输出2:
Hello Good Morning
In func t1
End of func main
有人能解释一下为什么goroutine不能保证执行该goroutine函数调用吗?
英文:
I am new to Go language programming and learning it step by step.
While practicing it, I found random behavior of goroutines.
If I call goroutine (function having sleep of 1 second), some times it completed successfully and some times it doesn't:
package main
import (
	"fmt"
	"time"
)
func t(i int) {
	fmt.Println("In func t")
	time.Sleep(1)
}
func t1(i int) {
	fmt.Println("In func t1")
	time.Sleep(1)
}
func main() {
	fmt.Println("Hello Good Morning")
	go t(1)
	t1(2)
	time.Sleep(5)
	fmt.Println("End of func main")
}
O/p 1 :
  Hello Good Morning
  In func t1
  In func t
  End of func main
O/p 2 :
  Hello Good Morning
  In func t1
  End of func main
Could someone explain why goroutine is not guaranteeing the execution of that goroutine function call.
答案1
得分: 1
程序执行:
当函数
main返回时,程序退出。它不会等待其他(非主)goroutine完成。
1- main也是一个goroutine,你需要等待其他goroutine完成,你可以使用
time.Sleep(5 * time.Second)
等待5秒钟,可以在Go Playground上尝试一下:
package main
import (
    "fmt"
    "time"
)
func t(i int) {
    fmt.Println("In func t")
    time.Sleep(1 * time.Second)
}
func t1(i int) {
    fmt.Println("In func t1")
    time.Sleep(1 * time.Second)
}
func main() {
    fmt.Println("Hello Good Morning")
    go t(1)
    t1(2)
    time.Sleep(5 * time.Second)
    fmt.Println("End of func main")
}
输出:
Hello Good Morning
In func t1
In func t
End of func main
并查看文档:
// Sleep暂停当前的goroutine,至少持续时间为d。 // 负数或零的持续时间会导致Sleep立即返回。 func Sleep(d Duration)
2- 你可以使用sync.WaitGroup等待其他goroutine完成,可以在Go Playground上尝试一下:
package main
import (
    "fmt"
    "sync"
    "time"
)
var w sync.WaitGroup
func say(s string) {
    for i := 0; i < 2; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
    w.Done()
}
func main() {
    w.Add(1)
    go say("A")
    w.Add(1)
    say("B")
    w.Wait()
}
输出:
B
A
A
B
英文:
> When the function main returns, the program exits. It does not wait
> for other (non-main) goroutines to complete.
1- main is goroutine too, you need to wait for other goroutines to finish, and you may use
time.Sleep(5 * time.Second)
for 5 Seconds wait, try it on The Go Playground:
package main
import (
	"fmt"
	"time"
)
func t(i int) {
	fmt.Println("In func t")
	time.Sleep(1 * time.Second)
}
func t1(i int) {
	fmt.Println("In func t1")
	time.Sleep(1 * time.Second)
}
func main() {
	fmt.Println("Hello Good Morning")
	go t(1)
	t1(2)
	time.Sleep(5 * time.Second)
	fmt.Println("End of func main")
}
output:
Hello Good Morning
In func t1
In func t
End of func main
And see Docs:
>     // Sleep pauses the current goroutine for at least the duration d.
>     // A negative or zero duration causes Sleep to return immediately.
>     func Sleep(d Duration)
2- You may use sync.WaitGroup to wait for other goroutines, try it on The Go Playground:
package main
import (
	"fmt"
	"sync"
	"time"
)
var w sync.WaitGroup
func say(s string) {
	for i := 0; i < 2; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
	w.Done()
}
func main() {
	w.Add(1)
	go say("A")
	w.Add(1)
	say("B")
	w.Wait()
}
output:
B
A
A
B
答案2
得分: 0
两件事情:
- 如果你在
main函数中没有显式等待goroutine完成,那么不能保证它会在程序退出之前完成。 time.Sleep()的参数类型是time.Duration,单位是纳秒。由于你几乎没有延迟,所以结果是随机的也就不足为奇了。如果你在main函数中睡眠更长的时间,你应该会看到两行都被打印出来(尽管不能保证)。
如果你需要等待goroutine完成,有多种方法可以实现(例如使用通道和sync.WaitGroup)。
你可以参考一下《Go语言之旅》1,或者查看《Effective Go》2。
英文:
Two things:
- If you return from 
mainwithout having explicitly waited for your
goroutine to finish, there's no guarantee that it will finish before
the program exits. - The argument type of 
time.Sleep()istime.Duration,
the units of which are nanoseconds. Since you're barely delaying at
all, it's not surprising that your results were random. If you sleep
for a more substantial amount of time inmain, you should see both
lines printed (although it isn't guaranteed). 
If you need to wait for a goroutine to finish, there are various ways to do that (e.g, channels and sync.WaitGroup).
You may want to go through A Tour of Go and/or take a look at Effective Go.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论