英文:
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
main
without 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论